sed コマンドはファイル内で正常に検索して置換し、新しいファイルのすべての内容を少し消去します。

sed コマンドはファイル内で正常に検索して置換し、新しいファイルのすべての内容を少し消去します。

test2.txtというファイルにこのxmlテキストがあります。

<This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2/>


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

ファイルに対してこの正規表現を実行します。最初の段落を渡したいのですが、ファイルの残りの部分はそのままにしておきます。

sed -i -En '/./{H;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/p' test2.txt

ただし、結果はsedコマンドがファイルの残りの文字列をすべて削除してregexp initに入れた結果であるため、test2.txtは次のようになります。

<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->

正規表現を実行しながらファイル内の他のテキストを保持するにはどうすればよいですか?

答え1

あなたはsedに明示的に言います。いいえ線がパターンと一致しない限り印刷します。したがって、演算子の後の合計を削除すると、期待-nどおりに機能します。ps///

$ sed  -E '/./{H;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file

<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

しかし、これはまだ最初に追加の改行を追加します。幸いなことに、@フィリフォスこの問題を解決する方法を教えてください。以下を使用してください。

$ sed -E '/./{H;1h;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file
<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

または、ソースファイルを編集します。

sed -i.bak -E '/./{H;1h;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file

答え2

データが一般的なXML文書(通常のXMLノード)を表すとします。できないプロパティに部分文字列が含まれる可能性があるため、提案した方法でコメントを処理してください。--これにより、コメントが早期に終了し、文書構造が破損する可能性があります。ノードを直接削除する方が安全です。これはXMLパーサーでは簡単です。

文書があると仮定すると

<?xml version="1.0"?>
<root>
  <thing alt="--" year="2019" month="1" day="1"/>
  <thing alt="--" year="2020" month="5" day="13"/>
  <thing year="2021" month="7" day="3"/>
</root>

thing...属性にその値を持つノードを削除するには、次のようにします。2020yearxmlstarlet

$ xmlstarlet ed -d '//thing[@year = "2020"]' file.xml
<?xml version="1.0"?>
<root>
  <thing alt="--" year="2019" month="1" day="1"/>
  <thing year="2021" month="7" day="3"/>
</root>

xmlstarlet-L()オプションで内部編集をサポートします--inplace

関連情報