sed 是一个出色的工具,可以在单行上进行简单替换,对于其他任何内容,只需使用 awk 即可。如果您在 sed 中使用除 s、g 和 p(带有 -n)以外的任何内容,那么您使用的是错误的工具和语言结构,这些工具和语言结构在 20 世纪 70 年代中期 awk 发明时就已经过时了。
有很多方法可以做到这一点。这是一个:
$ cat file1
<plist>
<dict>
.
.
<key>abc</key>
<dict>
.
.
</dict>
.
.
</dict>
</plist>
.
$ cat file2
now is the
winter of
our discontent
.
$ awk 'NR==FNR{extra = extra $0 RS; next} {print} /<dict>/ && ++count==1{printf "%s", extra}' file2 file1
<plist>
<dict>
now is the
winter of
our discontent
.
.
<key>abc</key>
<dict>
.
.
</dict>
.
.
</dict>
</plist>
想要在 dict 第二次出现而不是第一次出现后打印?只是改变==1
to ==2
:
$ awk 'NR==FNR{extra = extra $0 RS; next} {print} /<dict>/ && ++count==2{printf "%s", extra}' file2 file1
<plist>
<dict>
.
.
<key>abc</key>
<dict>
now is the
winter of
our discontent
.
.
</dict>
.
.
</dict>
</plist>
想要搜索跨越多行的模式而不是第 N 次出现的模式?以下是使用 GNU awk 实现多字符 RS 和 gensub() 的一种方法:
$ awk -v RS='^$' 'NR==FNR{extra=$0;next} {print gensub(/<plist>[[:space:]]+<dict>\n/,"&"extra,"")}' file2 file1
<plist>
<dict>
now is the
winter of
our discontent
.
.
<key>abc</key>
<dict>
.
.
</dict>
.
.
</dict>
</plist>
所有与 awk 相关的琐事。
要使用任何 UNIX 命令更新原始文件,请执行以下操作:
command file > tmp && mv tmp file
所以在这种情况下是:
awk 'script' file > tmp && mv tmp file
GNU awk 有一个-i inplace
与 sed 类似的参数-i
如果您喜欢边际简洁,请在幕后创建 tmp 文件:
awk -i inplace 'script' file