ファイルから文字列を検索し、それを変数として使用するには?

ファイルから文字列を検索し、それを変数として使用するには?

次の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最後のラインではなくすべてのラインのパターン空間が除去されるため、一致を待つブロック全体でのみ変更が発生します。!$Hx<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 Gh

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

関連情報