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
程序可用于生成唯一的临时文件名.
有一些黑客可以避免临时文件,但它们主要依赖于缓存和读取缓冲区,并且对于较大的文件很快就会变得不稳定.
自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时使用双引号(如果不这样,则不会有换行符).
当在一句话中看到“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)
您也可以sponge
从moreutils中使用。
例如
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。