Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save modifications in place with awk

Tags:

linux

unix

awk

People also ask

Can awk edit in place?

Overview. Both the awk command and the sed command are powerful Linux command-line text processing utilities. We know that the sed command has a handy -i option to edit the input file “in-place”. In other words, it can save the changes back to the input file.

Does awk overwrite a file?

Unfortunately, in system awk command, there is no direct option to overwrite the input file. So what you need to do is to redirect the output to a temporary file and then use mv command to overwrite your input file using the temporary file.

What is awk '{ print $1 }'?

If you notice awk 'print $1' prints first word of each line. If you use $3, it will print 3rd word of each line.


In GNU Awk 4.1.0 (released 2013) and later, it has the option of "inplace" file editing:

[...] The "inplace" extension, built using the new facility, can be used to simulate the GNU "sed -i" feature. [...]

Example usage:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3

To keep the backup:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3

Unless you have GNU awk 4.1.0 or later...

You won't have such an option as sed's -i option so instead do:

$ awk '{print $0}' file > tmp && mv tmp file

Note: the -i is not magic, it is also creating a temporary file sed just handles it for you.


As of GNU awk 4.1.0...

GNU awk added this functionality in version 4.1.0 (released 10/05/2013). It is not as straight forwards as just giving the -i option as described in the released notes:

The new -i option (from xgawk) is used for loading awk library files. This differs from -f in that the first non-option argument is treated as a script.

You need to use the bundled inplace.awk include file to invoke the extension properly like so:

$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print $1}' file

$ cat file
123
456
789

The variable INPLACE_SUFFIX can be used to specify the extension for a backup file:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

I am happy this feature has been added but to me, the implementation isn't very awkish as the power comes from the conciseness of the language and -i inplace is 8 characters too long i.m.o.

Here is a link to the manual for the official word.


just a little hack that works

echo "$(awk '{awk code}' file)" > file

@sudo_O has the right answer.

This can't work:

someprocess < file > file

The shell performs the redirections before handing control over to someprocess (redirections). The > redirection will truncate the file to zero size (redirecting output). Therefore, by the time someprocess gets launched and wants to read from the file, there is no data for it to read.


An alternative is to use sponge:

awk '{print $0}' your_file | sponge your_file

Where you replace '{print $0}' by your awk script and your_file by the name of the file you want to edit in place.

sponge absorbs entirely the input before saving it to the file.