我需要使用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“
答案 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>