【发布时间】:2011-12-22 14:34:15
【问题描述】:
awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt
它正在显示输出,但我想将输出写入同一个文件。在我的例子中testfile.txt。
【问题讨论】:
awk '/^nameserver/ && !modif { printf("nameserver 127.0.0.1\n"); modif=1 } {print}' testfile.txt
它正在显示输出,但我想将输出写入同一个文件。在我的例子中testfile.txt。
【问题讨论】:
本身不可能。您需要第二个临时文件,因为您无法读取和覆盖同一个文件。比如:
awk '(PROGRAM)' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt
mktemp 程序可用于生成唯一的临时文件名。
有一些技巧可以避免临时文件,但它们主要依赖于缓存和读取缓冲区,并且对于较大的文件很快就会变得不稳定。
【讨论】:
mv -f testfile.tmp testfile.txt 覆盖文件
从 GNU Awk 4.1.0 开始,就有了“就地”扩展,所以你可以这样做:
$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3
要保留原始文件的备份副本,请尝试以下操作:
$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3
这可用于模拟 GNU sed -i 功能。
【讨论】:
尽管使用临时文件是正确的,但我不喜欢它,因为:
您必须确保不要擦除另一个临时文件(是的,您可以使用 mktemp - 这是一个非常有用的工具)
您必须小心删除它(或像 thiton 所说的那样移动它),包括当您的脚本崩溃或在结束前停止时(因此在脚本末尾删除临时文件不是那么明智)
它在磁盘上生成 IO(没那么多,但我们可以让它更轻)
所以我避免临时文件的方法很简单:
my_output="$(awk '(PROGRAM)' source_file)"
echo "$my_output" > source_file
请注意在从 awk 命令获取输出和使用 echo 时使用双引号(如果不这样做,则不会有换行符)。
【讨论】:
您也可以使用moreutils 中的sponge。
例如
awk '!a[$0]++' file|sponge file
删除重复的行和
awk '{$2=10*$2}1' file|sponge file
将第二列乘以 10。
【讨论】:
在一句话中看到'awk'和'not possible'时不得不说明。这是一个仅 awk 的解决方案,无需创建临时文件:
awk '{a[b++]=$0} END {for(c=1;c<=b;c++)print a[c]>ARGV[1]}' file
【讨论】:
尝试在您的 awk 文件中包含语句,以便您可以在新文件中找到输出。这里的总计是一个计算值。
print $total, total >> "new_file"
【讨论】:
这种内联写作对我有用。将 print 的输出重定向回原始文件。
echo "1" > test.txt
awk '{$1++; print> "test.txt"}' test.txt
cat test.txt
#$> 2
【讨论】: