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:
<plist>
<dict>
.
.
<key>abc</key>
<dict>
.
.
</dict>
.
.
</dict>
</plist>
we want to insert few lines after finding the first dict tag.
If I use follow command it inserts after all dict tag in file.
sed -i '' "/<dict>/ r template" info.plist
So, I tried to find plist and dict tag and insert lines after that.
sed -i '' "/<plist version=\"1.0\">\n<dict>/r template" info.plist
or
sed -i '' "/\(^<plist version=*.\)/ r template" info.plist
This also doesn't work for this it is not able to find the pattern in file.
Please suggest me how can I put a pattern which contains two strings separated by newline.
这可能适合你(GNU sed):
sed -i -e '1,/<dict>/{/<dict>/{r template' -e '}}' file
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
尝试使用'N'命令启用换行符匹配:
sed 'N;/<plist>\n\s\+<dict>/a added line' info.plist
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.