Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sed:在最后一次出现后追加_Sed - Fatal编程技术网

Sed:在最后一次出现后追加

Sed:在最后一次出现后追加,sed,Sed,假设我有以下类型的文件: <?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-466c27c9

假设我有以下类型的文件:

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

1.
{Preferences}widgets/opera-adblock-1.3.4-1.oex
{Preferences}widgets/flag-button-1.5.4-1.oex
我的任务是在上次出现
之后添加文本

看看这两个,似乎利用
tac
会更简单,但我也不知道如何做到这一点:


谢谢。

要在最后一个节标记后插入文本,即在结尾的“首选项”标记前插入文本:

要将其作为管道执行,请执行以下操作:

cat file.xml | ...whatever... | sed 's#</preferences>#  HELLO\n&#'
cat file.xml |…随便什么…|塞德的###你好&#
请注意,在XML上使用
sed
和正则表达式往往会导致问题,因为XML既不是基于regexp的,也不是基于行的。要做得更好,请在perl、python、ruby、java等语言中使用真正的XML解析器。

一种方法:

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

在字符串第一次出现之前添加内容更容易:

sed '/<\/preferences>/i\ADD SOME TEXT\nADD SOME MORE TEXT' file
sed'//i\添加一些文本\n添加更多文本”文件
结果:

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

1.
{Preferences}widgets/opera-adblock-1.3.4-1.oex
{Preferences}widgets/flag-button-1.5.4-1.oex
添加一些文本
添加更多文本

您可以阅读有关如何在字符串前插入行的更多信息。HTH.

使用awk,您可以这样做

awk '$0 ~ /<\/pref/{print "Hello\n"$0}' temp.txt
awk'$0~/这可能对您有效(GNU sed):

本质上:当遇到包含
/节的行时,开始将所有剩余行存储到保留空间(HS)中文件的末尾。如果行已在保留空间中,并且遇到另一行,则在HS中打印行并再次开始存储行。在文件末尾插入所需字符串并打印出存储的行

上面的答案是正确的,但它包含一个导致它在OS X上失败的怪癖。编码多行插入
sed
脚本的正确、可移植的方法是:

  • 在实际内容前面加一个换行符
  • 用反斜杠转义每个换行符(包括命令后的第一行)
  • 下面是一个更新的示例,给出了您最初帖子中的文本:

    sed -i '' '/<\/preferences>/i\
    ADD SOME TEXT\
    ADD SOME MORE TEXT\
    ' test.xml
    
    …并从以下方面:


    这是我在最后一个
    #include
    之后添加一行的方法

    grep -n '#include' $file | tail -1 | cut -f1 -d: | xargs -I % echo %+1 | bc | 
    xargs -I '{}' sed -i '{}i// clang-format off' $file
    
    • 获取最后一次出现的行号并向其添加1
    • 使用sed在线条处插入线条

    为什么不在第一次出现
    之前添加它?@Blender,嗯,因为我很笨。那么我该怎么做呢?
    cat file.xml | sed
    是对
    cat
    的无用使用:
    sed
    可以读取
    file.xml
    directly@sputnick好的观点;我将在回答中澄清这一点。谢谢与其写两次
    ,不如像joelparkerhenderson那样将模式分组或使用
    &
    符号?这会让你的眼睛更容易阅读一行字,这是不正确的。新文本必须出现在一个全新的行上。@ELLIOTTCABLE:是的。你真的学过这个例子吗?是的
    sed:1:“//i\ADD…”:在i命令末尾的\后面加上额外字符
    Ahhah。事实证明,与Mac OS X上的
    sed
    相比,gnu
    sed
    对这一规则的分析要少一些。也就是说,gnu
    sed
    和OS X
    sed
    的手册页面都是这样描述的;这是官方要求的,而且更便于携带,可以将内容放在新的行上。谢谢。其他人都在解决OP的问题,这当然对他们和网站的大部分要点都非常有用。你是唯一一个回答问题的人(你仍然发布了一个有助于OP的解决方案),这有助于像我这样来自谷歌、有类似问题的人。
    <?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>
    
    awk '$0 ~ /<\/pref/{print "Hello\n"$0}' temp.txt
    
    Hello
    </preferences>
    
    sed '/\/section/{x;/./p;x;h;d};x;/./!{x;b};x;H;$!d;x;s/\/section[^\n]*\n/&  HELLO\n/' file
    
    sed -i '' '/<\/preferences>/i\
    ADD SOME TEXT\
    ADD SOME MORE TEXT\
    ' test.xml
    
         [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
    
           text   Append text, which has each embedded newline preceded by a back-
              slash.
    
           i \
    
           text   Insert text, which has each embedded newline preceded by a back-
              slash.
    
           q      Immediately  quit  the  sed  script  without processing any more
              input, except that if auto-print is  not  disabled  the  current
    
    grep -n '#include' $file | tail -1 | cut -f1 -d: | xargs -I % echo %+1 | bc | 
    xargs -I '{}' sed -i '{}i// clang-format off' $file