Change string with awk

I am trying to do a single line replacement in a file with awk like

changing this:

e1 is (on) e2 is (off) 

to:

 e1 is (on) e2 is (on) 

use command:

 awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba 

this makes a replacement, but the file ends up empty!

+6
source share
5 answers

Another answer using another tool (sed and the -i flag (in place))

 sed -i '/e2/ s/off/on/' ~/Documents/Prueba 
+18
source

Your awk is correct, however you are redirected to the same file as your original. This causes the source file to be overwritten before it is read. You will need to redirect the output to another file.

 awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba.new 

Rename Prueba.new after that, if necessary.

+17
source

You can also use cat to read the file first, then use pipe to redirect to stdout, then read with awk from stdin:

 cat ~/Documents/Prueba | awk '/e2/{gsub(/off/, "on")};{print}' - > ~/Documents/Prueba 

I think dash is optional, since you are only reading stdin.

Some interesting documentation: https://www.gnu.org/software/gawk/manual/html_node/Naming-Standard-Input.html

+2
source

As explained in other answers and in the question β€œ Why reading and writing the same file using I / O redirection leads to an empty file on Unix? ”, Shell redirection destroys your input file before it is read.

To solve this problem without explicitly accessing temporary files, review the sponge command from moreutils .

 awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba | sponge ~/Documents/Prueba 

Alternatively, if GNU awk is installed on your system, you can use the placement extension .

 gawk -i inplace '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba 
+2
source

You cannot redirect to the same file as the input file. Choose a different file name.

> will delete your file first.

0
source

Source: https://habr.com/ru/post/909648/


All Articles