すべて削除するノード != タグ値

すべて削除するノード != タグ値

ここでは XML パーサーが理想的な方法であることはわかっていますが、利用できるものはなく、私の環境に追加することもできません。

次の構造に従う XML を取り上げます。

<CONTAINER>
  <FOLDER NAME="I_RS_INT">
  </FOLDER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
  <FOLDER NAME="I_RS_TRN">
  </FOLDER>
</CONTAINER>

bashスクリプトでは、<FOLDER NAME=一致するすべてのノードを削除する*RS*か、一致するすべてのノードを削除します。<FOLDER NAME != $var_folder

ご協力いただければ幸いです。

答え1

これで完了です:

cat /tmp/xml  | sed -e '/<FOLDER NAME=.*RS.*>/ { N; d; }'

2 つの文字の間のパターンに一致するすべての行について/、{} 内のコードが実行されます。N は次の行もパターン スペースに取り込み、次に d は次の行に移動する前にすべてを削除します。これは、POSIX 互換のsed.

<FOLDER NAME=.*RS.*>との間のすべての行を削除するには、以下を試してください</FOLDER.>

 awk '/<FOLDER NAME=.*RS.*>/,/<\/FOLDER>/ {next} {print}' xmlfile

このnextコマンドは、現在の一致の処理を停止します。その後に単純な を続けますprint

答え2

これはXMLパーサーを使って行う必要があります。例えば、XMLスターレットコマンドラインで:

$ xmlstarlet ed -d '/CONTAINER/FOLDER[contains(@NAME, "RS")]' data.xml
<?xml version="1.0"?>
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

または、

$ var="I_R_INR"
$ xmlstarlet ed -d "/CONTAINER/FOLDER[@NAME != '$var']" data.xml
<?xml version="1.0"?>
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

最初の例では部分文字列の一致が実行され、2 番目の例では完全一致が実行されることから、これら 2 つは同等ではないことに注意してください。


xqラッパーを巻くとjq:

$ xq -x --arg substring "RS" 'del(.CONTAINER.FOLDER[] | select(."@NAME" | contains($substring)))' file.xml
<CONTAINER>
  <FOLDER NAME="I_R_INR"></FOLDER>
</CONTAINER>
$ xq -x --arg name "I_R_INR" 'del(.CONTAINER.FOLDER[] | select(."@NAME" != $name))' file.xml
<CONTAINER>
  <FOLDER NAME="I_R_INR"></FOLDER>
</CONTAINER>

答え3

冗談抜きで、正規表現でXMLを解析するのは悪いニュースXML は正規言語ではないため、正規表現では正しく処理できません。その結果、記述したものはすべてハッキーで脆弱なものになります。

ただし、 には とXML呼ばれる正規表現に似たものがありますxpath

あなたの問題に対処するには、次のようにします:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
#process the file as XML
my $twig = XML::Twig -> parsefile ( 'your_file.xml' );

#iterate 'FOLDER' elements
foreach my $folder ( $twig -> get_xpath ('//FOLDER' ) ) {
   #delete any that regex match /RS/
   if ( $folder -> att('NAME') =~ m/RS/ ) { 
      $folder -> delete;
   }
}

#print the result. 
$twig -> set_pretty_print('indented_a');
$twig -> print;

答え4

sed -r '/<FOLDER NAME=.*RS.*>/{ :X N; /<\/FOLDER>/d; bX }' file
<CONTAINER>
  <FOLDER NAME="I_R_INR">
  </FOLDER>
</CONTAINER>

関連情報