Overwrite File Without Truncating
In Bash, when you open a file for writing, the file gets truncated. However, there is a way to open a file for both reading and writing at the same time.
Who hasn’t made the mistake of creating a process that tries to both read and write to the same file?
$ wc -c file
17 file
$ sed s/foo/FOO/ <file >file
$ wc -c file
0
Oops. That’s why for sed(1) in particular you use the
-i[SUFFIX], --in-place[=SUFFIX] switch, and in general can use
sponge(1) from moreutils (e.g. grep foo <file | sponge >file).
But you can also open a file for reading and writing, by using the
[n]<>word syntax. This is described in bash(1) under
“REDIRECTION” > “Opening File Descriptors for Reading and Writing”:
The redirection operator
[n]<>wordcauses the file whose name is the expansion of
wordto be opened for both reading and writing on file descriptorn, or on file descriptor0ifnis not specified. If the file does not exist, it is created.
Test drive:
$ cd $(mktemp -d)
$ ls
$ cat > test
Hello, world!
^D
$ cat >> test
Another line
^D
$ cat 1<> test
G'day^D
$ cat test
G'day, world!
Another line