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.

Tags:

Linux

Shell

Awk