sed:使用换行符在特定模式后插入行

时间:2014-05-22 10:13:56

标签: ios regex bash sed

我们想修改一个plist文件,这样在匹配一个模式后,它应该使用sed shell命令插入几行。

plist文件格式如下:

<plist> 
   <dict>
     .
     .
     <key>abc</key>
     <dict>
        .
        .
     </dict>
     .
     .
    </dict>
</plist>

我们想在找到第一个dict标签后插入几行。

如果我使用follow命令,它会在文件中的所有dict标签之后插入。

sed -i '' "/<dict>/ r template" info.plist

所以,我试图在那之后找到plist和dict标签并插入行。

sed -i '' "/<plist version=\"1.0\">\n<dict>/r template" info.plist

sed -i '' "/\(^<plist version=*.\)/ r template" info.plist

这也不起作用,因为它无法在文件中找到模式。

请建议我如何放置一个包含两行换行符的图案。

3 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -i -e '1,/<dict>/{/<dict>/{r template' -e '}}' file

答案 1 :(得分:1)

sed是一个很好的工具,可以在一行上进行简单的替换,对于任何其他只使用awk的东西。如果您在sed中使用除s,g和p(以及-n)之外的任何内容,那么您使用的是错误的工具和语言结构,这些结构在1970年代中期发明时已经过时了。

有很多方法可以做到这一点。这是一个:

$ 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>

想要搜索跨越多行的模式而不是模式的第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参数,就像seds -i一样,如果你更喜欢边缘简洁,就可以在后台创建tmp文件:

awk -i inplace 'script' file

答案 2 :(得分:0)

尝试使用&#39; N&#39;命令启用换行符匹配:

sed 'N;/<plist>\n\s\+<dict>/a added line' info.plist