Save modifications in place with awk

LinuxUnixAwk

Linux Problem Overview


I am learning awk and I would like to know if there is an option to write changes to file, similar to sed where I would use -i option to save modifications to a file.

I do understand that I could use redirection to write changes. However is there an option in awk to do that?

Linux Solutions


Solution 1 - Linux

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

Solution 2 - Linux

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.

Solution 3 - Linux

just a little hack that works

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

Solution 4 - Linux

@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.

Solution 5 - Linux

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.

Solution 6 - Linux

following won't work

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

this should work

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

Solution 7 - Linux

In case you want an awk-only solution without creating a temporary file and usable with version!=(gawk 4.1.0):

awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDeanoView Question on Stackoverflow
Solution 1 - LinuxlindView Answer on Stackoverflow
Solution 2 - LinuxChris SeymourView Answer on Stackoverflow
Solution 3 - LinuxYuri G.View Answer on Stackoverflow
Solution 4 - Linuxglenn jackmanView Answer on Stackoverflow
Solution 5 - LinuxCodoscopeView Answer on Stackoverflow
Solution 6 - LinuxFlowmix LeonsioView Answer on Stackoverflow
Solution 7 - LinuxHawkView Answer on Stackoverflow