【发布时间】:2021-12-02 11:36:18
【问题描述】:
例如,我试图用 awk 替换文件中的一行
改变这个:
e1 is (on)
e2 is (off)
到:
e1 is (on)
e2 is (on)
使用命令:
awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba
这会进行替换,但文件以空白结尾!
【问题讨论】:
例如,我试图用 awk 替换文件中的一行
改变这个:
e1 is (on)
e2 is (off)
到:
e1 is (on)
e2 is (on)
使用命令:
awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba
这会进行替换,但文件以空白结尾!
【问题讨论】:
另一个答案,使用不同的工具(sed 和 -i(就地)标志)
sed -i '/e2/ s/off/on/' ~/Documents/Prueba
【讨论】:
您的 awk 是正确的,但是您正在重定向到与原始文件相同的文件。这导致原始文件在被读取之前被覆盖。您需要将输出重定向到不同的文件。
awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba > ~/Documents/Prueba.new
如有必要,之后重命名 Prueba.new。
【讨论】:
正如其他答案和问题“Why reading and writing the same file through I/O redirection results in an empty file in Unix?”中所解释的那样,shell 重定向会在您的输入文件被读取之前破坏它。
要在不显式使用临时文件的情况下解决该问题,请查看moreutils 集合中的sponge 命令。
awk '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba | sponge ~/Documents/Prueba
或者,如果您的系统上安装了 GNU awk,您可以使用 in place extension。
gawk -i inplace '/e2/{gsub(/off/, "on")};{print}' ~/Documents/Prueba
【讨论】:
你也可以先用cat读取文件,然后用pipe重定向到stdout,再用awk从stdin读取:
cat ~/Documents/Prueba | awk '/e2/{gsub(/off/, "on")};{print}' - > ~/Documents/Prueba
我相信破折号- 是可选的,因为您只是在阅读标准输入。
一些有趣的文档:https://www.gnu.org/software/gawk/manual/html_node/Naming-Standard-Input.html
【讨论】:
【讨论】: