エスケープされたスラッシュとエスケープされていないスラッシュを含む文字列があります。
脱出のためのsed代替品を探していますエスケープされていないスラッシュのみしかし、否定的なLookBehindをサポートしていないようです。
例:
input: "https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"
desired output: "https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"
答え1
sed
使用POSIX基本正規表現デフォルトでは、Perl準拠の正規表現言語で一般的に見られる予測アサーションと他の幅がゼロのアサーションは除外されます。
代わりに、エスケープされたスラッシュを解放し、変更された文字列のすべてのスラッシュをエスケープします。
sed -e 's@\\/@/@g' -e 's@/@\\/@g'
まず、すべてのインスタンスをに変更し、\/
次に/
すべて/
をに変更します\/
。これは@
、置換コマンドを防ぐための代替区切り記号です。傾いたつまようじ症候群(ほとんどすべての他の文字を使用できます)。
例:
$ echo '"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"' | sed -e 's@\\/@/@g' -e 's@/@\\/@g'
"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"
テキスト行がシェルの文字列に格納されている場合は、bash
次のようにできます。
$ string='"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"'
$ string=${string//\\\///} # leaning toothpick warning!
$ string=${string//\//\\/}
$ printf '%s\n' "$string"
"https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com"
上記は変数置換を使用して${variable//pattern/replacement}
inをすべてに置き換えます。pattern
$variable
replacement
答え2
Perl では LookBehind を使用できます。
$ input="https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https://baz/test.com"
$ printf '%s\n' "$input" | perl -pe 's|(?<!\\)/|\\/|g'
https:\/\/github.com\/foo\/bar\/pull\/2934) is live at https:\/\/baz\/test.com
答え3
これはトリックを行う必要があります
sed 's:\\\?/:\\/:g'
ゼロまたは1つのバックスラッシュが前にあるスラッシュをエスケープされたスラッシュに置き換えます。
答え4
sedにはLookBehindの断言はありませんが、シミュレーションできます。これには、拡張正規表現モード(-E)のGNU sedが表示されます。
sed -E '
:a
s:(^|[^\])(([\][\])*)[/]:\1\2\\/:
t a
' file
バックスラッシュではないことを確認するか、行の先頭に到達する前に/左側に偶数のバックスラッシュがあることを確認してください(0は偶数です)。