1

awk (推奨)、sed、または perl を使用した 1 つのソリューションについて助けが必要です。ソリューションは、bash シェル スクリプト内に統合する必要があります。これが私の問題です。次のように、ant ビルド ファイル ターゲットのターゲット内に 1 行を挿入する必要があります。

<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

name="XXXX"その build.xml ファイルには多くのターゲット名がありますが、常に一意であることに注意してください。他のすべてのターゲットの終了セパレーターは と同じ</target>です。行は行の前に挿入する必要があることに注意して</target> ください...build.xmlは多くのターゲットを含むラグファイルであり、単語「name="-XXXX」は一意ですが、「-XXXX」という単語ではないことに注意してください

4

5 に答える 5

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
于 2012-08-22T09:17:14.623 に答える
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>
于 2012-08-22T08:59:37.920 に答える
1

これはsedユーティリティで実行できます:

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

sedファイルの正しい<target>...</target>部分のみを考慮するように指示し</target>、追加した行 に置き換えて、</target>

于 2012-08-22T09:01:09.453 に答える
1

$inside簡単な Perl ソリューション:目的のターゲット内にいるかどうかを示すフラグを使用します。

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 ;
于 2012-08-22T08:56:27.727 に答える
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>
于 2012-08-22T09:18:21.710 に答える