如何使用awk在ant构建文件目标范围内插入一行

时间:2012-08-22 08:34:43

标签: perl sed awk

我需要使用awk(最好),sed或perl来解决一个解决方案。 解决方案应该在bash shell脚本中进行插入。这是我的问题, 我需要在ant build file target的目标中插入一行,如下所示:

<target name="-AAAA" unless="non_AAAA_buildpackage">
              <antcall target="init"/>
              many antcall lines
</target>
<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              many antcall lines here
              The line should be inserted here  as <antcall target="ZZZZ"/>
</target>
<target name="-BBBB" unless="non_BBBB_buildpackage">
              <antcall target="init"/>
              many antcall lines here
</target>
many targets here as this is a large file

请注意,build.xml文件中有许多目标名称,但name="XXXX"是。{1}} 总是独特的。所有其他目标的结束分隔符与</target>相同。 请注意,该行应插入行之前... </target> 请注意,build.xml是一个带有许多目标和单词“name =” - XXXX“是唯一的但不是单词” - XXXX“

的延迟文件

5 个答案:

答案 0 :(得分:1)

Simple Perl解决方案:使用标记$inside来告诉您是否在所需目标内:

perl -pe ' $inside = 1 if /<target name="-XXXX"/;
           print qq(              <antcall target="ZZZZ"/>\n) if $inside and m{</target>};
           $inside = 0 if m{</target>};
         ' 1.xml

或者,使用XML::LibXML包装XML::XSH2

open 1.xml ;
insert chunk { qq(              <antcall target="ZZZZ"/>\n) } append //target[@name="-XXXX"] ;
save ;

答案 1 :(得分:1)

使用GNU sed

infile的内容:

<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              ...............
              <antcall target="YYYY"/>
              <antcall target="ZZZZ"/>  **###The line should be inserted here**
</target>
<target name="-YYYY" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              ...............
              <antcall target="YYYY"/>
              <antcall target="ZZZZ"/>  **###The line should be inserted here**
</target>

script.sed的内容:

/^<target[ \t]\+name="-XXXX"/,/^<\/target>/ {
        /^<\/target>/ { i\
Your line                                                                                                                                                                                                                                   
        }
}

像以下一样运行:

sed -f script.sed infile

使用以下输出:

<target name="-XXXX" unless="non_XXXX_buildpackage">                                                                                                                                                                                         
              <antcall target="init"/>                                                                                                                                                                                                       
              ...............                                                                                                                                                                                                                
              <antcall target="YYYY"/>                                                                                                                                                                                                       
              <antcall target="ZZZZ"/>  **###The line should be inserted here**                                                                                                                                                              
Your line                                                                                                                                                                                                                                    
</target>                                                                                                                                                                                                                                    
<target name="-YYYY" unless="non_XXXX_buildpackage">                                                                                                                                                                                         
              <antcall target="init"/>                                                                                                                                                                                                       
              ...............                                                                                                                                                                                                                
              <antcall target="YYYY"/>                                                                                                                                                                                                       
              <antcall target="ZZZZ"/>  **###The line should be inserted here**                                                                                                                                                              
</target>

答案 2 :(得分:1)

这适用于sed实用程序:

sed -i -e '/-XXXX/,/<\/target>/s/<\/target>/NEWLINEINSERTEDHERE\n<\/target>/' infile

我们告诉sed仅考虑文件的正确<target>...</target>部分,然后我们将</target>替换为您添加的行</target>

答案 3 :(得分:1)

使用awk执行此操作:将记录分隔符设置为</target>,然后将其固定在正确的位置:

awk -v RS='</target>' -v ORS='' -v OFS='' '
{ print }
/name="-XXXX"/ { print "              INSERTED LINE", "\n" }
{ print RT }'

应该做你需要的。输出记录和字段分隔符应为空以获得正确的空格。

更新

在新数据上运行上述脚本的示例:

<强>的build.xml

<target name="-AAAA" unless="non_AAAA_buildpackage">
              <antcall target="init"/>
              many antcall lines
</target>
<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              many antcall lines here
              The line should be inserted here  as <antcall target="ZZZZ"/>
</target>
<target name="-BBBB" unless="non_BBBB_buildpackage">
              <antcall target="init"/>
              many antcall lines here
</target>
many targets here as this is a large file

运行脚本:

awk -v RS='</target>' -v ORS='' -v OFS='' '
{ print }
/name="-XXXX"/ { print "\t\t<antcall target=\"ZZZZ\"/>", "\n" }
{ print RT }' build.xml > out.tmp

请注意,您需要转义双引号。另请注意,如果您希望在添加的行前添加标签,请在print语句中添加适当的金额。

<强> out.tmp

<target name="-AAAA" unless="non_AAAA_buildpackage">
              <antcall target="init"/>
              many antcall lines
</target>
<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              many antcall lines here
              The line should be inserted here  as <antcall target="ZZZZ"/>
              <antcall target="ZZZZ"/>
</target>
<target name="-BBBB" unless="non_BBBB_buildpackage">
              <antcall target="init"/>
              many antcall lines here
</target>
many targets here as this is a large file

验证添加:

diff build.xml out.tmp

输出:

8a9                        
> <antcall target="ZZZZ"/>

修改

这是一个更便携的脚本版本:

awk 'BEGIN { RS="</target>"; ORS=""; OFS="" }
{ print }
/name="-XXXX"/ { print "\t\t<antcall target=\"ZZZZ\"/>", "\n" }
{ print RS }' build.xml > out.tmp

答案 4 :(得分:0)

> cat temp
<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              <antcall target="YYYY"/>
</target>

一个awk解决方案:

> awk '{if($0~/\/target/){p="\t<antcall target=\"ZZZZ\"/>\n"$0;print p}else print}' temp
<target name="-XXXX" unless="non_XXXX_buildpackage">
              <antcall target="init"/>
              <antcall target="YYYY"/>
        <antcall target="ZZZZ"/>
</target>