私はこれらの3行を見つけようとしています:
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
そしてそれらを次のものに置き換えます:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
私がしようとすると
Sudo sed -i 's:<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
見つかりません。\ nを追加しようとしましたが、まだ機能しませんでした。
Sudo sed -i 's:<!--\n <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />\n -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
これらはエラーをスローせず、行のコメントを解除しません。どんなアドバイスでも感謝します!
sedは各行を順番に読み取るため、正しい方向に微調整しない限り、複数行のパターンに一致することはありません。 N
コマンドは、入力から1行を読み取り、それをパターンスペースに追加します。
sed -i -e '/^<!--$/ {
N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
N; /\n-->$/ {
s/^<!--\n//; s/\n-->$//
}
}
}' /myfile.xml
おそらく、s
以外のコマンドが必要な場合は、sedからawkまたはPerlに切り替える必要があります。以下は、より一般的な方法で複数行コメントに対処する、やや柔軟なPerlスニペットです。
Perl -i -pe '
if (/<!--/) { $_ .= <> while !/-->/;
s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
}' /myfile.xml
Sedは行単位で動作します。複数のラインで動作するように作成することはできますが、そのようには設計されていません。そして、私の意見では、そのように使用しようとすると、はっきりと表示されます。しかし、その方法を選択する場合は、おそらくレジスタを使用する必要があります。 https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n のいくつかのソリューションを確認して、どのように実行できるかを確認してください。
この種のタスクでは、sedではなくPerlを使用することを好みます(つまり、複数行指向です)。検索と置換の前に追加する必要があるボイラープレート(BEGIN...
)は明らかではありませんが、正規表現は私にはきれいに見えます:
Perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml
または、グループ化を使用して式を短くし、そこで正規表現を使用できるようにします。
Perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml
コメントマーカーとコメント解除するコードの間に改行がある場合とない場合の両方で機能します。
原作:
https://stackoverflow.com/questions/1030787/multiline-search-replace-with-Perl
SEDの複数行コマンドの説明は次のとおりです。 http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm
お尻の痛みです。エドゥアルドのアドバイスに従い、Perl -i -p -e
代わりに。
/<\!--/
:一致する文字列:X
:これは分岐コマンド "b"のラベルです/-->/
:一致する文字列s@...@...@p
:「<!-」、「->」を取り除いて結果を出力するd
:パターンスペースを削除して新しいサイクルを開始N
:/-> /と一致しない場合は、行を追加しますbX
::Xラベルへの分岐p
:/ <!-/と一致しない文字列を出力するだけですsed -rn '
/<!--/ {
:X
/-->/ {
s@<!--\s*(<.+/>)\s*-->@\1@p
d
}
N
bX
};p'
この2番目の方法は、通常の小さなサイズのテキストファイルを単純にコピーアンドペーストしたものです(シェルスクリプトファイルが必要です)。
#!/bin/bash
# copy & paste content that you want to substitute
AA=$( cat <<\EOF | sed -z -e 's#\([][^$*\.#]\)#\\\1#g' -e 's#\n#\\n#g'
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
EOF
)
BB=$( cat <<\EOF | sed -z -e 's#\([&\#]\)#\\\1#g' -e 's#\n#\\n#g'
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
EOF
)
sed -z -i 's#'"${AA}"'#'"${BB}"'#g' *.xml # apply to all *.xml files