How to change a file in-place using awk? (as with "sed -i")
GNU awk
(commonly found on Linux systems), since version 4.1.0, is able to include an "awk
source library" with -i
or --include
on the command line. One of the source libraries that is distributed with GNU awk
is one called inplace
:
$ cat file
hello
there
$ awk -i inplace '/hello/ { print "oh,", $0 }' file
$ cat file
oh, hello
As you can see, this makes the output of the awk
code replace the input file. The line saying there
is not kept as it's not outputted by the program.
With an awk
script in a file, you would use it like
awk -i inplace -f script.awk datafile
If the awk
variable INPLACE_SUFFIX
is set to a string, then the library would make a backup of the original file with that as a filename suffix.
awk -i inplace -v INPLACE_SUFFIX=.bak -f script.awk datafile
If you have several input files, then each file with be individually in-place edited. But you can turn in-place editing off for a file (or a set of files) by using inplace=0
on the command line before that file:
awk -i inplace -f script.awk file1 file2 inplace=0 file3 inplace=1 file4
In the above command, file3
would not be edited in-place.
For a more portable "in-place edit" of a single file, use
tmpfile=$(mktemp)
cp file "$tmpfile" &&
awk '...some program here...' "$tmpfile" >file
rm "$tmpfile"
This would copy the input file to a temporary location, then apply the awk
code on the temporary file while redirecting to the original filename.
Doing the operations in this order (running awk
on the temporary file, not on the original file) ensures that file meta-data (permissions and ownership) of the original file is not modified.
Try this.
awk new.awk sample.csv > tmp.csv && mv -f tmp.csv sample.csv
- redirect the output to a temp file.
- then move content of temp file to original file.