9

I have an awk file new.awk

 BEGIN { FS=OFS="," }
 NR==1 {
for (i=1; i<=NF; i++) {
    f[$i] = i
}
   } 
  NR > 1 {
 begSecs= mktime(gensub(/[":-]/," ","g",$(f["DateTime"])))
 endSecs = begSecs + $(f["TotalDuration"])
 $(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
 }
 { print }

I am calling this file in shell

awk new.awk sample.csv

But I can see the changes in the terminal, but how to make the change permanent to the file like using -i in sed.

15

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.

4

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.
  • 1
    If you look at the awk inplace source code this is exactly what it does: creates a temporary file, redirects stdout there and at the end renames it to the input file. – chx Jan 23 at 12:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.