次のXMLファイルがあります。
<id>456</id>
<root>
<value>1</value>
<intNum>2</intNum>
</root>
<root>
<eulav>1</eulav>
<muNtni>2</muNtni>
</root>
<id>456</id>
私は覚えて、次のことをしたいと思います。
sed 's/\<root\>/\
\<root\>
$herecomestheid
基本的にこれがすること<root>
はに置き換えることです<root>\n<id>456</id>
。\n
この場合、改行を意味します。私はすでにこれを知っていますが、私が経験している問題はそれを覚えて、<id>456</id>
後で使用するために保管することです。
私はこれを試しました(明らかにうまくいきません)。
sed -i '' 's/\<root\>/\
\<root\>\
\<id\>.\<\/id\>/g'
私は次のようにします:
cat file.xml | grep '\<id\>*\<\/id\>'
grep出力を変数に入れてみてください。これも明らかに動作しません。
編集: <id>*</id>
ルートディレクトリにある必要があります。
答え1
XMLをテキストとして扱うのは一般的に信頼できる解決策ではありませんが、そうする必要があると主張する場合はsedを使用できます。スペアスペース 例えば
sed -e '/<id>[0-9]*<\/id>/h' -e '/<root>/{x;p;x;}' file.xml
答え2
sed -e :b -e '$!{N;\|<id>.*\n<root>|!bb
};do what ever you want to do with all of those lines now....'
私はoldspaceがおそらく最良の選択であるというSteeldriverのコメントに同意しますh
が、他のオプションもあります。時々、私たちは2つのバッファを管理するにはあまりにも怠惰です。またはこれは通常私の問題です。はい2つのバッファを管理します。上記のコードスニペットはパターン空間に行を重ねます。をする常にタグの間に表示され<id>
、ライン2に移動する前に常に必要なデータチャンクでパターンスペースを再帰的に埋めます。つまり、バッファが同時に崩壊しない限り、そうします。しかし、今はそうするのがやや難しいです。。
h
また、以前の宇宙問題に戻り、電子的x
変化は交換 h
古くてパターン化された空間。一度使用すると、モードバッファがh
前のバッファにレンダリングされ、その逆も同様です。この効果はラインサイクル中持続します。私がよくやっていることは、開始線に達するまでファイルを読み、予備編集を実行してから、別のH
状態が得られるまで以前の状態を交換して維持することです。私のスクリプトが再び変更されると、1ブロック遅れます。最後に開いたタグH
と同時にすべてのフィールドが遅れます。必要に応じて必要なだけバッファリングする簡単な方法です。
所望のループを達成する別の方法は以下の通りである。
sed -e '/<id>/h;//!H;/<root>/!{$!d' -e '};x...'
その時点からパターン空間はH
以前の空間となり、その逆も同様です。h
昔の意志書く h
前のスペースが使用されるたびに、現在のモードスペースと共に使用されます。したがって、上記の例では、<id>
毎回1行で新しいバッファを起動します。!H
追加H
前のスペースのすべての中間行の後に\n
行文字が続きます。現在のラインが安全に入り、次のラインループが始まると、$!d
最後のラインではなくすべてのラインのパターン空間が除去されるため、一致を待つブロック全体でのみ変更が発生します。!
$
H
x
<root>
あなたのそれを覚えなさいついに<root>
ブロックすると、一致と異なる場合はタグが最後の行になることがあります。
しかし...
編集内容によると脱出できない理由がないと思われます。
sed '/<id>/h;//d;\|</root>|G
' <<\INPUT
unimportant 1
<id> number 1 </id>
<root> sub text
more text
more text
</root>
<root> sub text as well
and more text
and more text
</root>
unimportant 2
<id> number 2 </id>
<root> sub text
more text
more text
</root>
<root> sub text
and more text
and more text
</root>
INPUT
フィールド<id>
の行があります。h
(もう一度言うが、h
古いスペースを上書きする)その後、d
出力から削除します。一致が発生すると、</root>
ラインサイクルの終わりに結果が自動的に印刷される前に、前のスペースがパターンスペースに追加されます。sed
G
h
unimportant 1
<root> sub text
more text
more text
</root>
<id> number 1 </id>
<root> sub text as well
and more text
and more text
</root>
<id> number 1 </id>
unimportant 2
<root> sub text
more text
more text
</root>
<id> number 2 </id>
<root> sub text
and more text
and more text
</root>
<id> number 2 </id>
答え3
使用されたawk
ソリューション
awk '/<id>/{id=$0}/<root>/{print id}1' file.xml
その行を印刷したくない場合は、を<id>
追加してスキップできますnext
。
awk '/<id>/{id=$0;next}/<root>/{print id}1' file.xml