Linux 使用 awk 将修改保存到位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16529716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:55:46  来源:igfitidea点击:

Save modifications in place with awk

linuxunixawk

提问by Deano

I am learning awkand I would like to know if there is an option to write changes to file, similar to sedwhere I would use -ioption to save modifications to a file.

我正在学习awk,我想知道是否有一个选项可以将更改写入文件,类似于sed我使用-i选项将修改保存到文件的位置。

I do understand that I could use redirection to write changes. However is there an option in awkto do that?

我知道我可以使用重定向来编写更改。但是有没有awk办法做到这一点?

采纳答案by lind

In latest GNU Awk (since 4.1.0 released), it has the option of "inplace" file editing:

在最新的 GNU Awk(自4.1.0 发布以来)中,它具有“就地”文件编辑选项:

[...] The "inplace" extension, built using the new facility, can be used to simulate the GNU "sed -i" feature. [...]

[...] 使用新工具构建的“就地”扩展可用于模拟 GNU“ sed -i”功能。[...]

Example usage:

用法示例:

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

To keep the backup:

要保留备份:

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

回答by Chris Seymour

Unless you have GNU awk 4.1.0 or later...

除非你有 GNU awk 4.1.0 或更高版本......

You won't have such an option as sed's -ioption so instead do:

你不会有像 sed 的-i选项这样的选项,所以改为:

$ awk '{print 
$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print }' file

$ cat file
123
456
789
}' file > tmp && mv tmp file

Note: the -iis not magic, it is also creating a temporary file sedjust handles it for you.

注意:这-i不是魔术,它还会创建一个临时文件sed来为您处理它。



As of GNU awk 4.1.0...

从 GNU awk 4.1.0 开始...

GNU awkadded this functionality in version 4.1.0 (released 10/05/2013). It is not as straight forwards as just giving the -ioption as described in the released notes:

GNU awk在 4.1.0 版(10/05/2013 发布)中添加了此功能。它并不像-i发布说明中描述的那样直接提供选项:

The new -i option (from xgawk) is used for loading awk library files. This differs from -f in that the first non-option argument is treated as a script.

新的 -i 选项(来自 xgawk)用于加载 awk 库文件。这与 -f 的不同之处在于第一个非选项参数被视为脚本。

You need to use the bundled inplace.awkinclude file to invoke the extension properly like so:

您需要使用捆绑的inplace.awk包含文件来正确调用扩展,如下所示:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print }' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

The variable INPLACE_SUFFIXcan be used to specify the extension for a backup file:

该变量INPLACE_SUFFIX可用于指定备份文件的扩展名:

someprocess < file > file

I am happy this feature has been added but to me, the implementation isn't very awkish as the power comes from the conciseness of the language and -i inplaceis 8 characters too long i.m.o.

我很高兴已添加此功能,但对我而言,实现并不是很笨拙,因为强大的功能来自语言的简洁性,并且imo-i inplace8 个字符太长了。

Here is a link to the manualfor the official word.

这是官方单词手册的链接。

回答by glenn Hymanman

@sudo_Ohas the right answer.

@sudo_O有正确答案

This can't work:

这行不通:

awk '{a[b++]=
echo "$(awk '{awk code}' file)" > file
} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file

The shell performs the redirections beforehanding control over to someprocess (redirections). The >redirection will truncate the file to zero size (redirecting output). Therefore, by the time someprocess gets launched and wants to read from the file, there is no data for it to read.

shell将控制权移交给某个进程(重定向之前执行重定向。该>重定向将文件截断至零大小(重定向输出)。因此,当某个进程启动并想要从文件中读取时,没有数据可供它读取。

回答by Hawk

In case you want an awk-only solution without creating a temporary file and usable with version!=(gawk 4.1.0):

如果您想要一个 awk-only 解决方案而不创建临时文件并且可以使用 version!=(gawk 4.1.0):

echo $(awk '{awk code}' file) > file

回答by Yuri G.

just a little hack that works

只是一个小技巧

echo "$(awk '{awk code}' file)" > file

回答by Flowmix Leonsio

following won't work

以下将不起作用

awk '{print 
 awk '{awk code}' file | tee file
}' your_file | sponge your_file

this should work

这应该有效

##代码##

回答by Codoscope

An alternative is to use sponge:

另一种方法是使用sponge

##代码##

Where you replace '{print $0}'by your awk script and your_fileby the name of the file you want to edit in place.

'{print $0}'用 awk 脚本和your_file要就地编辑的文件名替换的位置。

spongeabsorbs entirely the input before saving it to the file.

sponge在将输入保存到文件之前完全吸收输入。

回答by shaiki siegal

Using tee

使用三通

##代码##

the teecommand take place and executed after the awkcommand is finished due to the |.

tee命令走位和后执行awk命令完成因|