내 grep 표현식에서 탭 문자와 일치시키기 위해 $'string'을 사용해야 하는 이유는 무엇입니까?

내 grep 표현식에서 탭 문자와 일치시키기 위해 $'string'을 사용해야 하는 이유는 무엇입니까?

이 코드를 사용하면:

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또는 EREperl compatible regular expressions또는 이 있습니다 PCRE. 모든 언어는 약간 다른 구문을 사용합니다. 현재 버전은 GNU grep세 가지를 모두 지원하며 BRE기본값입니다. 옵션과 옵션을 ERE사용해야 합니다 . 귀하의 예제는 기본 및 확장 RE의 경우 백슬래시가 의미를 잃고 백슬래시 또는 문자 t와 일치하므로 에서만 작동합니다 . 아마도 기본적으로 지원되는 다른 언어에서 해당 패턴을 사용하고 있었을 것입니다 . 이는 가장 강력한 버전이기 때문에 의미가 있습니다. 아니면 어딘가에 있었을 수도 있습니다 .-EPCRE -P-P[\t]PCREalias grep='grep -P'

답변3

를 생략하면 첫 번째 줄이 작동합니다 ^. 아마도 효과가 있었지만 예상한 대로 작동하지 않았을까요? grep이렇게 중요한 점에서 그의 행동이 달라졌다는 게 의심스럽습니다 .

echo기본적으로 이스케이프 시퀀스를 변환하지 않습니다. 그러기 위해서는 가 필요합니다 -e. 쉘과 유사합니다. $'...'쉘이 이스케이프 시퀀스를 사용하도록 해야 합니다 .

관련 정보