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]<>word
causes the file whose name is the expansion of
word
to be opened for both reading and writing on file descriptorn
, or on file descriptor0
ifn
is 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