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색상예를 들어.