如何使用awk命令将查找输出写入同一文件

Ven*_*kat 27 bash shell awk

awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt
Run Code Online (Sandbox Code Playgroud)

它正在显示输出,但我想将输出写入同一文件.在我的例子中testfile.txt.

thi*_*ton 45

本身不可能.您需要第二个临时文件,因为您无法读取和覆盖同一文件.就像是:

awk '(PROGRAM)' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt
Run Code Online (Sandbox Code Playgroud)

mktemp程序可用于生成唯一的临时文件名.

有一些黑客可以避免临时文件,但它们主要依赖于缓存和读取缓冲区,并且对于较大的文件很快就会变得不稳定.


ken*_*orb 9

自GNU Awk 4.1.0以来,有"inplace"扩展,所以你可以这样做:

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

要保留原始文件的备份副本,请尝试以下操作:

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

这可以用来模拟GNU sed -i功能.

请参阅:启用就地文件编辑


小智 8

尽管使用临时文件是正确的,但我不喜欢它,因为:

  • 你必须确保不要删除另一个临时文件(是的,你可以使用mktemp - 这是一个非常有用的工具)

  • 你必须要注意删除它(或者像thiton所说的那样移动它)包括脚本崩溃或在结束前停止(因此在脚本末尾删除临时文件并不明智)

  • 它在磁盘上生成IO(确定不是那么多,但我们可以让它更轻)

所以我避免临时文件的方法很简单:

my_output="$(awk '(PROGRAM)' source_file)"
echo "$my_output" > source_file
Run Code Online (Sandbox Code Playgroud)

注意在从awk命令获取输出时和使用echo时使用双引号(如果不这样,则不会有换行符).


Haw*_*awk 8

当在一句话中看到“awk”和“不可能”时,必须记下一笔。这是一个仅使用 awk 的解决方案,无需创建临时文件:

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


Lri*_*Lri 5

您也可以spongemoreutils中使用。

例如

awk '!a[$0]++' file|sponge file
Run Code Online (Sandbox Code Playgroud)

删除重复的行并

 awk '{$2=10*$2}1' file|sponge file
Run Code Online (Sandbox Code Playgroud)

将第二列乘以10。