sed XML は x 行から始まり、次の行番号を返します。

sed XML は x 行から始まり、次の行番号を返します。

XMLからタグセクションを削除して停止するには、閉じるタグを見つける必要があります。

XMLの例

<SearchPattern> 
     <something></something>
</SearchPattern>

<OtherTag></OtherTag>

<SearchPatternHit2>
    <something></something>
</SearchPatternHit2>

繰り返し1以降の必須XML出力の例

<OtherTag></OtherTag>

<SearchPatternHit2>
    <something></something>
</SearchPatternHit2>

繰り返し2以降の必須XML出力の例

<OtherTag></OtherTag>

現在の試みでは、sedを使用して、次のように最初に表示される行番号を見つけます。

start_line = $(grep -n "<${SEARCH_PATTERN}" ${FILE_PATH} | head -1| cut -f1 -d':')

出力は行番号整数です。

その後、次を使用して閉じるタグ付きの行を取得しようとしました。

finish_line = $(sed -n "${start_line},$ !d;/<\/${LEADING_TAG}>/=" ${FILE_PATH} | head -1)

検索パターンの複数のインスタンスがある場合、終了行の結果が正しくないため、最初の終了マークが得られないと思います。

この例では、パターンは1行と7行にあります。最初のパスではstart_line = 1ですが、Finish_lineは期待どおりに3を返しません。

これら2つの値を取得した後に動作する単純なsedステートメントを呼び出します。

sed -i "${start_line}, ${finish_line}d" ${FILE_PATH}

各ブロックで閉じるタグラインを取得するより良い方法は何ですか?

答え1

XMLを編集する正しい方法は、スペースの追加や他の行レイアウトなどの表示形式の変更を処理できるXMLパーサーを使用することです。現在私の最もよい選択はですxmlstarlet

有効なXML文書が与えられた場合:/tmp/xml

<?xml version="1.0"?>
<root>
  <SearchPattern>
    <something/>
  </SearchPattern>

  <OtherTag/>

  <SearchPatternHit2>
    <something/>
  </SearchPatternHit2>

  <SearchPatternHit2>
    <something_else/>
  </SearchPatternHit2>
</root>

<searchPattern/>この部分は非常に簡単に取り外すことができます

xmlstarlet edit -d '//SearchPattern' /tmp/xml

重複した要素の1つを削除するには、配列参照(1から始まる)を含めます。

xmlstarlet edit -d '//SearchPatternHit2[1]' /tmp/xml

答え2

私は少しハッキングされた簡単な解決策を見つけましたが、システムに他のツールを置くことができないので、これは私の解決策です。

私のスクリプトは、各フラグメントをXMLに入れる前後に共通のコメントを追加します。その後、grepを使用して見つけることができ、同じ単純なsedステートメントを使用して簡単に削除できます。

新しいXML

1. <!-- START MY CONFIG ADDITIONS-->
2. <SearchPattern> 
2.      <something></something>
3. </SearchPattern>
4. <!-- END MY CONFIG ADDITIONS-- 
5.
6. <OtherTag></OtherTag>
7.
8. <!-- START MY CONFIG ADDITIONS--> 
9. <SearchPatternHit2>
10.     <something></something>
11. </SearchPatternHit2>
12. <!-- END MY CONFIG ADDITIONS-->

新しい変数

start_line=$(grep -n "<!-- START MY CONFIG ADDITIONS-->" ${FILE_PATH} | head -1 | cut -f1 -d':')
finish_line=$(grep -n "<!-- END MY CONFIG ADDITIONS-->" ${FILE_PATH} | head -1 | cut -f1 -d':')

パスワード

count=$(grep -c "<!-- START MY CONFIG ADDITIONS-->" ${FILE_PATH})

while [ $count -gt 0 ]; do
    start_line=$(grep -n "<!-- START MY CONFIG ADDITIONS-->" ${FILE_PATH} | head -1 | cut -f1 -d':')
    finish_line=$(grep -n "<!-- END MY CONFIG ADDITIONS-->" ${FILE_PATH} | head -1 | cut -f1 -d':')

    sed -i "${start_line}, ${finish_line}d" $FILE_PATH

    ((count--))
done

関連情報