Unixコマンドは、特定のテキストが表示されるまで上下にgrepします。

Unixコマンドは、特定のテキストが表示されるまで上下にgrepします。

「12345」がxml全体の一意のIDである次の例を考えてみましょう。

<Tag 1>
a
b
c
d
12345
x
y
z
</Tag 1>

提供されたIDのXMLファイルを取得する<Tag 1>には、私のファイルから「12345」をgrepし、それぞれ上下に移動するコマンドが必要です。</Tag 1>

答え1

XML対応パーサーを使用して、XMLから直接値を選択できます。まず、XMLフラグメントを変更して有効にし、次の場所に配置しますfile.xml

<?xml version="1.0"?>
<Tag_1>
a
b
c
d
12345
x
y
z
</Tag_1>

(1)要素名がわかったら、このコマンドを使用して値を選択できます。

xmlstarlet select -t -v '//Tag_1' file.xml

出力(前の空行を含むXMLによる):

a
b
c
d
12345
x
y
z

要素タグ名が本当に必要な場合は、もう一度追加できます。

xmlstarlet select -t -e Tag_1 -v '//Tag_1' file.xml; echo

どちらの場合も、セレクタは要素//Tag_1のすべての項目と一致しますTag_1。より正確にするには、XPathセレクタを使用して使用する必要があります。たとえば、このコードスニペットには次のstuffオプションがあります/root/item/Tag_1

<root>
    <item><Tag_1>stuff</Tag_1></item>
    <unwanted><Tag_1>nonsense</Tag_1></unwanted>
</root>

(2) 私は質問を間違って読んで、実際に欲しいものと一致する要素名が欲しいという事実にショックを受けました。この場合、より複雑な表現ただし、これにより、目的のテキストを含む直接要素名が提供されます12345

xmlstarlet select -t -m '//*[contains(text(), "12345")]' -m 'ancestor::*' -b -v 'name()' -n file.xml

出力

Tag_1

必要に応じて、このソリューションを使用して要素を識別し、以前のソリューションを使用してそのデータを抽出するか、このソリューションの表現を拡張してコンテンツを含めることができます。

xmlstarlet select -T -t -m '//*[contains(text(), "12345")]' -m 'ancestor::*' -b -v 'concat("<", name(), ">", ., "</", name(), ">")' -n file.xml

そうでない場合はxmlstarlet標準パッケージであり、インストールが非常に簡単であることに注意してください。または、システム管理者にインストールを依頼してください。

答え2

filenameがあると仮定すると、上記のtext.xml検索文字列からデータを取得したいと思います。12345

上記の内容をgrep

string=`grep -n 12345 text.xml | awk -F: '{print $1}'` && head -n -$(( string - 1 )) text.xml

出力は次のとおりです -

<Tag 1>
a
b
c
d

次のコンテンツをGrepしてください。

string=`grep -n 12345 text.xml | awk -F: '{print $1}'` && tail -n +$(( string + 1 )) text.xml

出力は次のとおりです -

12345
x
y
z
</Tag 1>

答え3

使用幸せ(以前のPerl_6)

~$ raku -MXML -e 'my @xml = open-xml($*ARGFILES.Str).getElementsByTagName("tag");  \
                  .put for @xml.grep(/12345/);'  file

RakuのXMLモジュールを使用してXMLを解析します。

https://github.com/raku-community-modules/XML

入力例:

<?xml version="1.0"?>
<catalog>
  <tag id="1">
  a
  b
  c
  d
  12345
  x
  y
  z
  </tag>
</catalog>

出力例:

<tag id="1">
  a
  b
  c
  d
  12345
  x
  y
  z
  </tag>

contentsタグを削除し(return)、先行スペースを含む-actersのみを返すには、charRakuにそれを提供するように依頼してください。linestrim

~$ raku -MXML -e 'my @xml = open-xml($*ARGFILES.Str).getElementsByTagName("tag").map(*.contents);  \
                  .trim-leading.put if .chars for @xml.grep(/12345/).lines;' file 
a
b
c
d
12345
x
y
z

https://raku.org

関連情報