sed : Insert lines after specific pattern with newline

前端 未结 3 1578
忘掉有多难
忘掉有多难 2021-01-28 05:12

We want to modify a plist file such that after matching a pattern it should insert few lines using sed shell command.

plist file format is as follow:

<         


        
相关标签:
3条回答
  • 2021-01-28 05:53

    This might work for you (GNU sed):

    sed -i -e '1,/<dict>/{/<dict>/{r template' -e '}}' file
    
    0 讨论(0)
  • 2021-01-28 05:55

    Try the the 'N'-command to enable newline matching:

    sed 'N;/<plist>\n\s\+<dict>/a added line' info.plist
    
    0 讨论(0)
  • 2021-01-28 06:02

    sed is an excellent tool for simple substitutions on a single line, for anything else just use awk. If you're using anything other than s, g, and p (with -n) in sed then you are using the wrong tool and language constructs that became obsolete in the mid-1970s when awk was invented.

    There's a lot of ways you could do this. Here's one:

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

    Want to print after the 2nd occurrence of dict instead of the first? Just change ==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>
    

    Want to search for a pattern spanning multiple lines instead of the Nth occurrence of a pattern? Here's one way with GNU awk for multi-char RS and 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>
    

    All trivial stuff with awk.

    To update the original file with any UNIX command is:

    command file > tmp && mv tmp file
    

    so in this case it's:

    awk 'script' file > tmp && mv tmp file
    

    GNU awk has a -i inplace argument that works like seds -i to create the tmp file behind the scenes if you prefer the marginal brevity:

    awk -i inplace 'script' file
    
    0 讨论(0)
提交回复
热议问题