【问题标题】:How can I can insert the contents of a file into another file right before a specific line如何在特定行之前将文件的内容插入另一个文件
【发布时间】:2010-03-25 00:14:50
【问题描述】:

如何使用 sed 将文件的内容插入到另一个文件的特定行之前?

示例我的 file1.xml 包含以下内容:

        <field tagRef="376">
        </field>
        <field tagRef="377">
        </field>
        <field tagRef="58">
        </field>
        <group ref="StandardMessageTrailer" required="true"/>
    </fieldList>
</message>

file2.xml 有以下内容:

        <field tagRef="9647">
            <description>Offset</description>
        </field>
        <field tagRef="9648">
            <description>Offset Units/Direction</description>
        </field>
        <field tagRef="9646">
            <description>Anchor Price</description>
        </field>

如何将 file2 的内容插入到 file1 之前

<group ref="StandardMessageTrailer" required="true"/>

所以它看起来像这样:

       <field tagRef="376">
        </field>
        <field tagRef="377">
        </field>
        <field tagRef="58">
        </field>
        <field tagRef="9647">
            <description>Offset</description>
        </field>
        <field tagRef="9648">
            <description>Offset Units/Direction</description>
        </field>
        <field tagRef="9646">
            <description>Anchor Price</description>
        </field>
        <group ref="StandardMessageTrailer" required="true"/>
    </fieldList>
</message>

我知道如何使用

在该行之后插入
sed 'group ref="StandardMessageTrailer"/r file2.xml' file1.xml > newfile.xml  

但我想在之前插入它。

感谢帮助

【问题讨论】:

  • 我很想看到一个实际的 sed 解决方案 - 我知道它应该可以通过 /StandardMessageTrailer/{x;r insert;G} 之类的东西来实现,但这还不够......

标签: sed


【解决方案1】:
f2="$(<file2)"
awk -vf2="$f2" '/StandardMessageTrailer/{print f2;print;next}1' file1 

如果你想要 sed,这里有一种方法

sed  -e '/StandardMessageTrailer/r file2' -e 'x;$G' file1

【讨论】:

  • 您的sed 版本不打印file1 的最后一行。如果您在'x' 之后添加-e '$G',那么它将失败,但如果带有正则表达式的行是file1 中的最后一行,则通过打印该行然后 file2 的内容,它将失败。跨度>
  • @dennis 谢谢。关于最后一行正则表达式问题。我敢打赌它不会发生,现在。 :) 如您所见,我首选的解决方案不是 sed。
  • 在 MacOS 上,您可以通过在命令中添加 -i.bak 来直接将更改写入文件:sed -i.bak -e '/StandardMessageTrailer/r file2' -e 'x;$G' file1
【解决方案2】:

如果你能承受两次传球,你可以用记号笔:

sed '/Standard/i MARKER' file1.xml | sed -e '/MARKER/r file2.xml' -e '/MARKER/d'

尝试一次性完成的问题在于,除了“r”之外,没有其他方法(据我所知)插入文件的内容,而“r”在输出流中这样做,在操作范围,之后 sed 完成了该行。因此,如果“标准”位于最后一行,那么在 file2 出现时,您对它所做的任何事情都将结束。

【讨论】:

    【解决方案3】:

    我通常是这样的:

    1. file1,要读取插入内容的文件
    2. file2,将file1中的读取内容插入到file2的头部
    3. 脚本 sn-p:

      sed "\$r ${file2}" ${file1} &gt; tmpfile
      mv tmpfile ${file2}

    【讨论】:

      【解决方案4】:

      以下是对我有用的解决方案:

      1. 使用像explained in another reply这样的标记:

        sed '/StandardMessageTrailer/i MARKER' file1.xml | sed -e '/MARKER/r file2.xml' -e '/MARKER/d'
        
      2. 计数发生时的行like explained in another reply to a similar question

        LINE_NUMBER_MATCHING=$(sed -n '/StandardMessageTrailer/=' file1.xml) && sed "$((${LINE_NUMBER_MATCHING} - 1))r file2.xml" file1.xml
        
      3. 或者使用 sed like explained in another reply to a similar question:

        sed $'/StandardMessageTrailer/{e cat file2.xml\n}' file1.xml
        

      【讨论】:

        【解决方案5】:

        我尝试了不同的解决方案,而来自 Beta 的解决方案为我完成了工作。

        总结:

        • 我想在一个主文件中插入不同的文件
        • 我想用标记来说明我希望将这些文件插入到哪里

        示例:
        创建 2 个文件:

        cloud_config.yml:

        coreos:
        __ETCD2__
        

        etcd2.yml:

          etcd2:
            name:                         __HOSTNAME__
            listen-peer-urls:             http://__IP_PUBLIC__:2380
            listen-client-urls:           http://__IP_PUBLIC__:2379,http://127.0.0.1:2379
        

        然后我们在上面运行该脚本:

        sed '/Standard/i __ETCD2__' cloud_config.yml \
        | sed -e "/__ETCD2__/r etcd2.yml" > tmpfile
        sed "s|__ETCD2__||g" tmpfile > cloud_config.yml
        

        终于,我们得到了:

        coreos:
          etcd2:
            name:                         __HOSTNAME__
            listen-peer-urls:             http://__IP_PUBLIC__:2380
            listen-client-urls:           http://__IP_PUBLIC__:2379,http://127.0.0.1:2379
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-24
          • 2017-02-25
          • 2016-06-06
          • 1970-01-01
          • 2015-08-17
          • 1970-01-01
          • 2011-04-24
          • 1970-01-01
          相关资源
          最近更新 更多