入力ファイル:
<ServiceArea type="STATE" value="DC">
<DaylightSavingsUsed value="true"/>
<FemtoSipProxyAddress value="10.13.123.100"/>
<TermAuthAAAPSK value="secret1"/>
<PDSNDOParams index="1">
<batchEndIpAddress value="68.28.121.68"/>
<batchSecurityParameterIndex value="5262006"/>
<batchStartIpAddress value="68.28.121.68"/>
</PDSNDOParams>
<PDSNDOParams index="2">
<batchEndIpAddress value="68.28.113.68"/>
<batchIOSVersion value="tia-878-a"/>
<batchStartIpAddress value="68.28.113.68"/>
</PDSNDOParams>
<PDSN1XParams index="1">
<batchEndIpAddress value="68.28.121.68"/>
<batchSecretKey value="72563130317354663167345439615433"/>
<batchSecurityParameterIndex value="5262006"/>
<batchStartIpAddress value="68.28.121.68"/>
</PDSN1XParams>
<PDSN1XParams index="2">
<batchEndIpAddress value="68.28.113.68"/>
<batchIOSVersion value="tia-878-1"/>
</PDSN1XParams>
</ServiceArea>
<ServiceArea type="ZIP" value="66221">
</ServiceArea>
<ServiceArea type="FIPS" value="46081">
<DaylightSavingsUsed value="true"/>
<MTA_Number value="22"/>
<BC10_Utilization value="476,487,526"/>
</ServiceArea>
<ServiceArea type="FIPS" value="01824">
</ServiceArea>
間にデータがないすべての行を削除したいと思います。
<ServiceArea type=
</ServiceArea>
上記の入力から以下を削除する必要があります。
<ServiceArea type="ZIP" value="66221">
</ServiceArea>
そして
<ServiceArea type="FIPS" value="01824">
</ServiceArea>
答え1
スクリプト(スタイルシートとも呼ばれます)をxsltproc
使用してXMLファイルを処理できます。xslt
これには xslt スクリプトと制御 bash スクリプトが含まれます。たとえば、
dropem.xslt
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="ServiceArea">
<xsl:if test="count(*)>0">
<ServiceArea>
<xsl:copy-of select="node()"/>
</ServiceArea>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
dropem.sh
#!/bin/bash
cat <<EOF | xsltproc dropem.xslt - | tail -n +2
<ALL>
$(cat)
</ALL>
EOF
実際のコマンドは次のとおりです。
./dropem.sh < infile > outfile
注:xslt
スクリプトには、ServiceAreaノードと一致する「テンプレート」要素が含まれており、条件に基づいて(子ノードがある場合)それを結果にコピーします。
xsltproc
単一のXMLツリーのみが処理されるため、入力は閉じたタグペアでラップする必要があります。パッケージングはデータファイルをツリーにします。改行は出力に保持されず、出力はServiceAreaサブツリーのリストでもあります。
<?xml ...
ただし、必然的なプリアンブルと空の行の放出を防ぐために、出力は切り捨てられます。xsltproc
このアプローチの利点は、入力ファイルの行形式にあまり敏感でないことです。欠点は、あまりxslt
一般的でない言語を使用することです。
答え2
ノードをxmlstarlet
検出する方法に応じて、さまざまな方法でこれを実行できます。ServiceArea
すべての
ServiceArea
「テキストノード」ノードを削除します。xmlstarlet ed -d '//ServiceArea[text()]' file.xml
ServiceArea
子なしのすべてのノードを削除します。xmlstarlet ed -d '//ServiceArea[count(*)=0]' file.xml
どちらも文書形式が正しいかどうかによって異なります。サンプル文書には複数のルートノードが含まれているため、そうではありません。この問題を解決するのは簡単です。たとえば、文書の<root>
先頭と末尾に追加します。</root>
答え3
誰もが正しいXML解析ツールを使用してxmlを編集するように言うでしょうが、ServiceAreaタグが別々の行にあると仮定する簡単なawkスクリプトです。
awk '/<ServiceArea /{save = $0; next}
save!="" {
if(/<\/ServiceArea>/){ save = ""; next }
print save
save = ""
}
{ print }'
これにより、行が表示されたときに開始タグと一緒に保存されます。次の行を読み取るときに保存された行がありますが、現在の行が終了マークの場合は両方の行を抑制します。それ以外の場合は、保存した行を印刷してから現在の行を印刷します。