終了文字列が開始文字列とは異なるファイルから行を抽出しようとしています。
次の形式の入力ファイルがあります。
<item_id>6</item_id>
<info1>abc</info1>
<info2>123</info2>
<item_id>6</item_id>
<info1>def</info1>
<info2>456</info2>
<item_id>6</item_id>
<info1>ghi</info1>
<info2>789</info2>
<item_id>9</item_id>
<info1>jkl</info1>
<info2>012</info2>
<item_id>9</item_id>
<info1>mno</info1>
<info2>345</info2>
「6」から「9」まで抽出したい(9はランダムな数字です)
始まりは<item_id>6<\item_id>
終わりは<item_id>X<\item_id>
6ではありません
予想される結果:
<item_id>6</item_id>
<info1>abc</info1>
<info2>123</info2>
<item_id>6</item_id>
<info1>def</info1>
<info2>456</info2>
<item_id>6</item_id>
<info1>ghi</info1>
<info2>789</info2>
私は試した:
sed -n "/<item_id>6<\/item_id>/,/<item_id>!6<\/item_id>/p" input.file > output.6
sed -n "/<item_id>6<\/item_id>/,/<item_id>\!6<\/item_id>/p" input.file > output.6
sed -n "/<item_id>6<\/item_id>/,/<item_id>\{!6}<\/item_id>/p" input.file > output.6
sed -n "/<item_id>6<\/item_id>/,/<item_id>(6)\@!.<\/item_id>/p" input.file > output.6
sed -n "/<item_id>6<\/item_id>/,/<item_id>! 6<\/item_id>/p" input.file > output.6
答え1
これが正しい形式のXML文書であると仮定し、XMLStarletを使用してinfo_id
値のあるノードを選択し、兄弟ノードと6
それに続くノードを選択します。info1
info2
$ xmlstarlet sel -t -m '//item_id[. = 6]' \
-c . -nl \
-c './following-sibling::info1[1]' -nl \
-c './following-sibling::info2[1]' -nl file.xml
<item_id>6</item_id>
<info1>abc</info1>
<info2>123</info2>
<item_id>6</item_id>
<info1>def</info1>
<info2>456</info2>
<item_id>6</item_id>
<info1>ghi</info1>
<info2>789</info2>
または、次のノードの名前を無視してください。
xmlstarlet sel -t -m '//item_id[. = 6]' \
-c . -nl \
-c './following-sibling::*[1]' -nl \
-c './following-sibling::*[2]' -nl file.xml
答え2
おそらく、このGNU sedスクリプトはあなたに適しているでしょう:
sed '/<item_id>6<\/item_id>/{:1;n;/<item_id>[^6]<\/item_id>/{Q};b1};d' file
d
行が見つかるまで削除を続け、スクリプトが終了する([^ 6])行が見つかるまで、6
内部ループの各行を印刷し続けます。b1
not 6
Q
これは以下にのみ適用されることを理解してください。キャラクター数字(6
または9
)。
どんな数字でも動作するには非常に混乱しています(GNU)。
sed -e 'h;s,<item_id>\([0-9]*\)<\/item_id>,\1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>\([0-9]*\)<\/item_id>,\1,;t2;:3;g;n;b1};d;b;:2;/^6$/!Q;b3' file
いくつかの変数を使用する方が良いですが、それほど良くありません。
reg='<item_id>\([0-9]*\)<\/item_id>'
item='6'
sed -e "h;s,$reg,\1,;/^$item$/!d;/^$item$/{g;:1;h;s,$reg,\1,;t2;:3;g;n;b1};d;b;:2;/^$item$/!Q;b3" file
そしてPOSIXfyedは横説説のように見えます。
sed -ne 'h;s,<item_id>\([0-9]*\)<\/item_id>,\1,;/^6$/!d;/^6$/{g;:1;h;s,<item_id>\([0-9]*\)<\/item_id>,\1,;t2;:3;g;p;n;b1;};d;b;:2;/^6$/!q;b3' file
次の拡張コードだけが(?)読みやすくなります。
reg='<item_id>\([0-9]*\)<\/item_id>'
item='6'
sed -ne 'h; # hold copy of line being processed.
s,'"$reg"',\1,; # extract included number.
/^'"$item"'$/!d; # Not the correct number?: get next line.
/^'"$item"'$/{
g; # restore line from hold buffer.
:1
h; # store successive lines in hold buffer.
s,'"$reg"',\1,; # extract the number (again).
t2
:3
g; # restore the line back from hold buffer.
p; # print the line.
n; # go to process next line.
b1
}; # end of loop.
d; # avoid printing this last line.
q; # quit the sed script.
:2
/^'"$item"'$/!q; # Test if the number is the one selected.
b3
' file
たぶん他の言語やツールを使う必要があるかもしれません。