ファイルのテキストを複数行の文字列に置き換える

ファイルのテキストを複数行の文字列に置き換える

<asd>blablabla</asd>以下を含むXMLファイルがあります。

<dsa>-some stuff
-other stuff
final stuff.</dsa>

「asd」タグ間のすべての項目を「dsa」タグ間の項目に置き換えたいと思います。これはほぼ100%の数行です。タグ自体を変更するのではなく、タグ間のテキストだけを変更して改行を維持したいと思います。

ファイルは随時変更され、名前、拡張子、およびタグは同じままで、その間の内容のみが変更されます。

基本的なベアbash(Github Actionsで使用される種類)でこれを実行できるコマンドが必要です。

考えていますが、sed複数行に変えてどう言うべきかわかりません。

編集:私の間違い(おそらく?)は、私のファイルが実際のXMLファイルではなく実際に.net csprojファイルであったため、同様のコマンドが機能するかどうか
わからないということです。xmlstarlet

答え1

正しい形式のXML文書を想定します。

<root>
<asd>blablabla</asd>
<dsa>-some stuff
-other stuff
final stuff.</dsa>
</root>

次のように、xmlstarlet最上位asdノードの内容をそのノードの内容に簡単に置き換えることができます。dsa

$ xmlstarlet ed -u '/root/asd' -x '/root/dsa/text()' file.xml
<?xml version="1.0"?>
<root>
  <asd>-some stuff
-other stuff
final stuff.</asd>
  <dsa>-some stuff
-other stuff
final stuff.</dsa>
</root>

asd各ノードを兄弟ノードに置き換える必要があるより複雑な例は次のとおりですdsa

<?xml version="1.0"?>
<root>
  <node1>
    <asd>blablabla</asd>
    <dsa>-some stuff
-other stuff
final stuff.</dsa>
  </node1>
  <node2>
    <asd>REPLACE ME</asd>
    <dsa>REPLACE WITH THIS</dsa>
  </node2>
</root>

これは次の方法で行うことができます。

$ xmlstarlet ed -u '//asd' -x '../dsa/text()' file.xml
<?xml version="1.0"?>
<root>
  <node1>
    <asd>-some stuff
-other stuff
final stuff.</asd>
    <dsa>-some stuff
-other stuff
final stuff.</dsa>
  </node1>
  <node2>
    <asd>REPLACE WITH THIS</asd>
    <dsa>REPLACE WITH THIS</dsa>
  </node2>
</root>

答え2

この質問は以前に回答されました。sedを使用して複数行の文字列を置き換える方法は?

しかし、私はその投稿の2番目の答えであるuseを強くお勧めしますperl。多くの人がPERLを離れているかもしれませんが、もともとこのような用途に使用されていました。

$ perl -0777 -i.original -pe 's/a test\nPlease do not/not a test\nBe/igs' alpha.txt

ご覧のとおり、パターンには改行が許可されています。詳しくは、回答をご覧ください。

答え3

xmlstarletそれがオプションであれば - たぶんこれを経験するかもしれませんxmlstarlet GitHubの操作- それでは

$ cat file.xml
<?xml version="1.0"?>
<foo>
<asd>blablabla</asd>
<dsa>-some stuff
-other stuff
final stuff.</dsa>
</foo>

次のようなことができます

$ xmlstarlet edit --update '//asd' --value "$(xmlstarlet select -t -v '//dsa' file.xml)" file.xml
<?xml version="1.0"?>
<foo>
  <asd>-some stuff
-other stuff
final stuff.</asd>
  <dsa>-some stuff
-other stuff
final stuff.</dsa>
</foo>

引用:

答え4

いいですね。 XML対応パーサーを使用する必要があります。しかし、Perlの場合:

perl -0pe 'm!<dsa>(.*?)</dsa>!s and $a=$1;
           s!<asd>.*?</asd>!<asd>$a</asd>!s' example

関連情報