使用 Mac 的 sed 命令在匹配后插入多行

使用 Mac 的 sed 命令在匹配后插入多行

我有 2 个文件:-

xml文件

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>

b.xml

<project>
    <modelVersion>4.0.0</modelVersion>
</project>

我想<parent>...</parent>从 a.xml 复制并将其放在</modelVersion>b.xml 后面:-

这就是我所拥有的:-

PARENT=`awk '/<parent>/,/<\/parent>/' a.xml | tr '\n' ' '`
sed -i '' "s|</modelVersion>|</modelVersion> ${PARENT}|g" "b.xml"

虽然它有效,但它看起来相当未格式化,因为我必须用空格替换换行符,以防止sed抱怨未转义的换行符。

<project>
  <modelVersion>4.0.0</modelVersion>     <parent>         ...     </parent> 
</project> 

如何使 b.xml 看起来像这样?

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>

顺便说一句,我正在使用 Mac。

答案1

这应该有效。我费了一番功夫仅有的<parent>...</parent>影响and的第一次出现</modelVersion> *$- 否则它可以变得更简单。它还会a正确转义所有附加字符以防万一。

sed -e'/^ *<parent>/!d;:n'      \
    -e'$d;N;/\n *<.parent>/!bn' \
    -e's/[\[:space:]]/\\&/g'    \
    -e's|.*\(.\n\)|/<.modelVersion> *$/a\1&|;q' a.xml |
sed -e'1,/<\/modelVersion> *$/{' -f- -e\}       b.xml

我不能 100% 确定 BSDsed会识别-stdin。如果我没记错的话,但是,为了以防万一,如果需要,您可以将 替换-f-为开关和参数-f/dev/fd/0

sed这是第一个写入第二个sed标准输入的脚本:

/<.modelVersion> *$/a\
\ \ \ \ <parent>\
\ \ \ \ \ \ \ \ ...\
\ \ \ \ </parent>

当第二个与输入中的sed第一个匹配时</modelVersion> *$,它会附加字符串,如下所示:

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>

答案2

尝试一下awk

awk '/parent/,/\/parent/{s=s"\n"$0}/\/modelVersion/{$0=$0s}NR!=FNR' a.xml b.xml

sed使用临时文件

sed -n '/parent/,/\/parent/w part
        1!{
            /^.project/,${
                /\/modelVersion/r part
                p
                          }
           }' a.xml b.xml

或有保留空间

sed -n '/parent/,/\/parent/H
        1!{
           /^.project/,${
               /\/modelVersion/{
                   G
                   s/\n//
                       }
               p
                         }
           }' a.xml b.xml

相关内容