假设我有以下类型的文件:
<?xml version="1.0" encoding="utf-8"?>
<preferences>
<section id="widgets">
<value id="version" xml:space="preserve">1</value>
</section>
<section id="wuid-b2a8e6b8-6619-714e-9cfe-466c27c90902">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/opera-adblock-1.3.4-1.oex</value>
</section>
<section id="wuid-0c5cfdb2-8e51-f149-a1e7-51d66240ed7a">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/flag-button-1.5.4-1.oex</value>
</section>
</preferences>
我的任务是在最后一次出现</section>
后立即添加文字。
看看这两个似乎使用tac
会更简单,但我不明白如何做到这一点:Using sed to append a string to the fourth occurrence of a pattern,http://www.unix.com/unix-dummies-questions-answers/46294-add-line-after-last-occurnace-pattern.html#post302149709
感谢。
答案 0 :(得分:5)
这可能适合你(GNU sed):
sed '/\/section/{x;/./p;x;h;d};x;/./!{x;b};x;H;$!d;x;s/\/section[^\n]*\n/& HELLO\n/' file
实质上:在遇到包含/section
的行时,开始将所有剩余行存储到保留空间(HS)中文件的末尾。如果线已经在保持空间中并且遇到另一条这样的线,则打印HS中的线并再次开始存储线。在文件的末尾插入所需的字符串并打印出存储的行。
答案 1 :(得分:2)
要在最后一个标记之后插入文字,即在结束“首选项”标记之前插入文字:
sed 's#</preferences># HELLO\n&#' file.xml
输出如下:
...
</section>
HELLO
</preferences>
要做到这一点,请使用-i
标志:
sed -i 's#</preferences># HELLO\n&#' file.xml
将其作为管道:
cat file.xml | ...whatever... | sed 's#</preferences># HELLO\n&#'
首先使用sed
和XML上的正则表达式往往会导致问题,因为XML不是基于regexp的,也不是基于行的。要做得更好,请在perl,python,ruby,java等中使用真正的XML解析器。
答案 2 :(得分:2)
一种方式:
sed -i 's@</preferences>@ <section id="x">\n <value id="path to widget data" xml:space="preserve">{Preferences}widgets/xxxx</value>\n </section>\n&@' file.xml
此代码段在<section>
文件中添加了新的XML
。
<?xml version="1.0" encoding="utf-8"?>
<preferences>
<section id="widgets">
<value id="version" xml:space="preserve">1</value>
</section>
<section id="wuid-b2a8e6b8-6619-714e-9cfe-466c27c90902">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/opera-adblock-1.3.4-1.oex</value>
</section>
<section id="wuid-0c5cfdb2-8e51-f149-a1e7-51d66240ed7a">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/flag-button-1.5.4-1.oex</value>
</section>
<section id="x">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/xxxx</value>
</section>
</preferences>
答案 3 :(得分:2)
在第一次出现字符串之前添加内容更容易:
sed '/<\/preferences>/i\ADD SOME TEXT\nADD SOME MORE TEXT' file
结果:
<?xml version="1.0" encoding="utf-8"?>
<preferences>
<section id="widgets">
<value id="version" xml:space="preserve">1</value>
</section>
<section id="wuid-b2a8e6b8-6619-714e-9cfe-466c27c90902">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/opera-adblock-1.3.4-1.oex</value>
</section>
<section id="wuid-0c5cfdb2-8e51-f149-a1e7-51d66240ed7a">
<value id="path to widget data" xml:space="preserve">{Preferences}widgets/flag-button-1.5.4-1.oex</value>
</section>
ADD SOME TEXT
ADD SOME MORE TEXT
</preferences>
您可以阅读有关如何在字符串here之前插入行的详细信息。 HTH。
答案 4 :(得分:1)
用awk你可以这样做
awk '$0 ~ /<\/pref/{print "Hello\n"$0}' temp.txt
输出
Hello
</preferences>
答案 5 :(得分:1)
@Steve上面的回答是解决这个问题的正确方法,但它包含一个导致它在OS X上失败的怪癖。编码多行插入的正确,可移植的方式{{1} }脚本是:
这是一个更新的示例,给出了初始帖子中的文字:
sed
供参考,摘录自the OS X sed(1)
manpage,
sed -i '' '/<\/preferences>/i\
ADD SOME TEXT\
ADD SOME MORE TEXT\
' test.xml
...来自GNU sed(1)
manpage:
[2addr]H
Append a newline character followed by the contents of the pattern space to the hold space.
[1addr]i\
text Write text to the standard output.
[2addr]l
(The letter ell.) Write the pattern space to the standard output in a visually unambiguous
答案 6 :(得分:0)
这是我要在最后一个#include
之后添加一行的方法。
grep -n '#include' $file | tail -1 | cut -f1 -d: | xargs -I % echo %+1 | bc |
xargs -I '{}' sed -i '{}i// clang-format off' $file