sed:用换行符在特定模式之后插入行
我们想修改一个plist文件,在匹配一个模式之后,它应该使用sed shell命令插入几行。
plist文件格式如下:
<plist> <dict> . . <key>abc</key> <dict> . . </dict> . . </dict> </plist>
我们想要在find第一个字典标记后插入几行。
如果我使用follow命令,它插入文件中的所有字典标记。
sed -i '' "/<dict>/ r template" info.plist
所以,我试图findplist和dict标签,然后插入行。
sed -i '' "/<plist version=\"1.0\">\n<dict>/r template" info.plist
要么
sed -i '' "/\(^<plist version=*.\)/ r template" info.plist
这也不起作用,它无法find文件中的模式。
请build议我怎样才能把一个模式,其中包含由换行符分隔的两个string。
sed是一个简单的replace在一个单一的线上的优秀工具,其他的只是使用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
更改为==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>
想要search一个跨越多行而不是第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
inplace参数,像seds -i
一样在后台创buildtmp文件,如果你喜欢边际简洁的话:
awk -i inplace 'script' file
这可能适用于你(GNU sed):
sed -i -e '1,/<dict>/{/<dict>/{r template' -e '}}' file
尝试使用'N'命令来启用换行匹配:
sed 'N;/<plist>\n\s\+<dict>/a added line' info.plist