
이 코드를 사용하면:
echo -e '\t\t\tString' | grep '^[\t]*String'
일치하지 않기 때문에 결과는 비어 있지만 이는 다음과 같습니다.
echo -e '\t\t\tString' | grep $'^[\t]*String'
공장. 나는 "$" 문자를 그런 식으로 사용하지 않고 내 스크립트와 터미널에서 첫 번째 줄의 코드를 수백 번 사용했음이 틀림없다고 맹세하며 항상 작동하는 것 같았습니다. 최근에 뭔가 변화가 있었나요? 왜 "$" 문자가 필요한가요? 아니면 내가 뭔가 잘못하고 있는 걸까요?
답변1
ANSI-C 인용
Bash 매뉴얼에 따르면 이것은 다음과 같습니다.ANSI-C 인용. 설명서에는 다음과 같이 나와 있습니다.
형태의 단어$'문자열'특별 대우를 받습니다. 단어는 ANSI C 표준에 지정된 대로 대체된 백슬래시 이스케이프 문자를 사용하여 문자열로 확장됩니다.
실제로 이는 '\t'
탭 문자로 확장되지는 않지만 $'\t'
확장된다는 의미입니다. 출력은 using 과 동일해야 echo -e
하지만 요구 사항 없이 문자열을 사용하는 모든 곳에서 사용할 수 있습니다.명령 대체.
GNU sed와 같은 유틸리티는 자체적으로 이스케이프 문자 확장을 수행하지만 GNU grep은 그렇지 않습니다. grep이 아닌 Bash 셸은 ANSI-C 인용 문자열 내에서 이스케이프 문자를 확장합니다. ANSI-C 인용이 없으면 게시한 정규식에 입력과 일치하는 탭 문자가 포함되어 있지 않습니다.
답변2
정규식에는 단일 유형이 없다는 것을 알아야 합니다. 적어도 basic regular expressions
또는 BRE
(때로는 만 RE
), extended regular expressions
또는 ERE
및 perl compatible regular expressions
또는 이 있습니다 PCRE
. 모든 언어는 약간 다른 구문을 사용합니다. 현재 버전은 GNU grep
세 가지를 모두 지원하며 BRE
기본값입니다. 옵션과 옵션을 ERE
사용해야 합니다 . 귀하의 예제는 기본 및 확장 RE의 경우 백슬래시가 의미를 잃고 백슬래시 또는 문자 t와 일치하므로 에서만 작동합니다 . 아마도 기본적으로 지원되는 다른 언어에서 해당 패턴을 사용하고 있었을 것입니다 . 이는 가장 강력한 버전이기 때문에 의미가 있습니다. 아니면 어딘가에 있었을 수도 있습니다 .-E
PCRE
-P
-P
[\t]
PCRE
alias grep='grep -P'
답변3
를 생략하면 첫 번째 줄이 작동합니다 ^
. 아마도 효과가 있었지만 예상한 대로 작동하지 않았을까요? grep
이렇게 중요한 점에서 그의 행동이 달라졌다는 게 의심스럽습니다 .
echo
기본적으로 이스케이프 시퀀스를 변환하지 않습니다. 그러기 위해서는 가 필요합니다 -e
. 쉘과 유사합니다. $'...'
쉘이 이스케이프 시퀀스를 사용하도록 해야 합니다 .