perl
一致する文字列を着色するために使用します。
MATCH=aaa
printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g"
特殊文字を含む文字列を一致させようとするまではうまくいきます。
MATCH=/dev/
printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g"
その理由は、 をbash
置き換えると$MATCH
Perl が次の式を取得するためです。
perl -pe "s/(/dev/)/\e[1;31m\1\e[0m/g"
/
機能するにはバックスラッシュが必要です。
MATCH=\/dev\/
printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g"
MATCH
しかし、何が含まれるかはまったく知りませんでした。+
何でもすることができます(
。perl
文字を表現ではなく文字通り処理するように指示する方法はありますか?
修正する:
提案されたソリューションを使用すると、Joseph R.
次のエラーが発生します。
MATCH=/dev/
printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/\Q($MATCH)\E/\e[1;31m\1\e[0m/g"
Backslash found where operator expected at -e line 1, near ")\"
(Missing operator before \?)
Having no space between pattern and following word is deprecated at -e line 1.
syntax error at -e line 1, near "s/\Q(/dev/)"
Search pattern not terminated at -e line 1.
アップデート2:
これでエラーは発生しませんが、一致するものがないようです(着色なし)。
# MATCH=/dev/ ; printf "aaa\n/dev/aaa\nccc\n" | perl -pe 's/(\Q$ENV{MATCH}\E)/\e[1;31m\1\e[0m/g'
aaa
/dev/aaa
ccc
答え1
quotemeta
はい、一重引用符でPerl演算子を使用できます。
export MATCH=...
... | perl -pe 's/(\Q$ENV{MATCH}\E)/...
\Q
との間\E
(または指定されていない場合は正規表現の終わりまで\E
)は、メタ文字に特別な意味が与えられていないままそのまま処理されます。
均等に:
export MATCH=...
... | perl -pe '$sane=quotemeta $ENV{MATCH};s/($sane)/...
修正する
これがどのように行われるかいいえexport
:
MATCH=/dev/
printf "aaa\n/dev/aaa\nccc\n" \
| perl -pe "\$sane=quotemeta q{$MATCH};s/(\$sane)/\e[1;31m\$1\e[0m/g"
コードにバグがあります。\1
代替パターンでは逆参照()は使用できません。滑らかな引用符によるシェルの補間を防ぐには、一致変数()(ここで使用)をs///
使用する必要があります。$1
\$1
$1
通常、Perlを使用してシェーディング操作をたくさんする場合は、端末機能を処理するモジュールを使用することをお勧めします。確認する用語::ANSIカラー例えば。