sed
次の簡単な例で再現できる問題があります。
次の入力ファイルを検討してください(入力.txt):
C:\A\quick\brown\fox\ jumps over the lazy dog
C:\A\quick\brown\fox\ ran with the hounds
次の出力を生成したい
C:\Animal\ jumps over the lazy dog
C:\Animal\ ran with the hounds
sedを使用して単純なシェルスクリプトを作成しようとしましたが、必要な代替操作を実行できませんでした。これは私のスクリプトです。
FROM_PATTERN="C:\A\quick\brown\fox\"
TO_PATTERN="C:\Animal\"
#FROM_PATTERN="C:\\A\\quick\\brown\\fox\\" # Escaping backslash does not help either
#TO_PATTERN="C:\\Animal\\" # Escaping backslash does not help either
sed 's/$FROM_PATTERN/$TO_PATTERN/g' input.txt
#sed 's/"$FROM_PATTERN"/"$TO_PATTERN"/g' input.txt # Quoting the pattern does not help either
私が書いているbash
バージョンGNU bash, version 4.4.12(3)-release-(x86_64-unknown-cygwin)
答え1
\
非常に特別な:
- 内部二重引用符を含むシェルの引用演算子でそれ自体をエスケープし、行の連続を実行するために使用
"
でき$
ます`
。 s
の正規表現演算子(エスケープおよび新しい演算子の導入に使用されます)sed
。- command の代替部分で、それ自体および改行文字を
s
sed
エスケープできます (または一部の実装で C スタイルのエスケープシーケンスを導入する)。&
\n
sed
また、単一引用符で囲まれた文字列内では、シェルパラメータ拡張は行われません。
ここで欲しいものは次のとおりです。
\
文字の周りに二重引用符の代わりに一重引用符を使用してください。- コマンド
\
の左右を脱出s
- 拡張する必要がある変数の部分を二重引用符で囲みます。
from_regexp='C:\\A\\quick\\brown\\fox\\'
escaped_replacement='C:\\Animal\\'
sed "s/$from_regexp/$escaped_replacement/g" < your-file
または、次のように特殊文字を気にせずに固定文字列を置き換えることができるperl
場合は、代わりに使用できます。sed
from='C:\A\quick\brown\fox\'
to='C:\Animal\'
FROM=$from TO=$to perl -pe 's/\Q$ENV{FROM}\E/$ENV{TO}/g' < your-file
また、見ることができます「sed」置換に挿入された文字列がすべてのメタ文字をエスケープするかどうかを確認する方法ランダムな文字列を処理します。
答え2
これはLinuxシステムで実行されましたが、cygwinがLinuxのbashと同じように動作するかどうかはわかりません。
PC1:~> echo 'C:\A\quick\brown\fox\ jumps over the lazy dog' | sed -ne 's|\(C:\\A\).\+\\\+\(.\+\)|\1nimal\2|p'
C:\Animal jumps over the lazy dog
PC1:~> echo 'C:\A\quick\brown\fox\ ran with the hounds' | sed -ne 's|\(C:\\A\).\+\\\+\(.\+\)|\1nimal\2|p'
C:\Animal ran with the hounds
PC1:~>
そのため、グループキャプチャを使用して「A」を繰り返し、その後に「nimal」を追加しました。より明確にするために、スラッシュをあまり使用しないように、代替区切り記号として「|」を使用しました。
お役に立てば幸いです。