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

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

이 코드를 사용하는 경우:

echo -e '\t\t\tString' | grep '^[\t]*String'

일치하지 않기 때문에 결과는 비어 있지만 다음과 같습니다.

echo -e '\t\t\tString' | grep $'^[\t]*String'

일하다. 나는 스크립트와 터미널에서 코드의 첫 번째 줄을 100번 이상 사용했을 것이며 이와 같은 "$" 문자를 사용한 적이 없으며 항상 작동하는 것 같습니다. 최근에 달라진 점이 있나요? "$" 문자가 필요한 이유는 무엇입니까? 아니면 내가 뭔가 잘못하고 있는 걸까요?

답변1

ANSI-C 인용문

Bash 매뉴얼에 따르면 이것은 다음과 같습니다.ANSI-C 인용문. 설명서에는 다음과 같이 나와 있습니다.

단어를 형성하다$'문자열'특별대우를 받으세요. 단어는 ANSI C 표준에 지정된 대로 대체된 백슬래시 이스케이프 문자를 사용하여 문자열로 확장됩니다.

실제로 이는 '\t'탭으로 확장되지 않지만 $'\t'확장된다는 의미입니다. 출력은 using 과 동일해야 echo -e하지만, 문자열이 사용되는 모든 곳에서 사용할 수 있습니다.명령 대체.

GNU sed와 같은 유틸리티는 자체 이스케이프 문자 확장을 수행하지만 GNU grep은 그렇지 않습니다. Bash 셸(grep은 아님)은 ANSI-C 인용 문자열에서 이스케이프 문자를 확장합니다. ANSI-C 인용문이 없으면 게시한 정규식에 입력과 일치하는 탭 문자가 포함되지 않습니다.

답변2

정규식에는 단일 유형이 없다는 것을 알아야 합니다. 적어도 basic regular expressions또는 BRE(때때로 만 RE), extended regular expressions또는 EREperl compatible regular expressions또는 이 있습니다 PCRE. 이 언어들은 모두 약간 다른 구문을 사용합니다. 현재 버전은 GNU grep세 가지를 모두 지원하며 BRE기본값입니다. 옵션과 for 옵션을 ERE사용해야하기 때문입니다 . 귀하의 예는 기본 및 확장 RE에서만 작동하며 백슬래시는 의미를 잃고 백슬래시 또는 문자 t와 일치합니다. 기본적으로 지원되는 다른 언어에서 이 모드를 사용하고 있을 수도 있는데 , 이는 가장 강력한 버전이기 때문에 의미가 있습니다. 아니면 당신은 어딘가에 있을 수도 있습니다.-EPCRE -P-P[\t]PCREalias grep='grep -P'

답변3

.이 생략된 경우 첫 번째 줄이 유효합니다 ^. 작동할 수도 있지만 상상했던 방식이 아닐 수도 있나요? 나는 grep그 행동이 중요한 시점에서 바뀌었다고 생각합니다.

echo이스케이프 시퀀스는 기본적으로 번역되지 않습니다. 당신은 -e이것이 필요합니다. 껍질과 비슷합니다. $'...'쉘이 이스케이프 시퀀스를 사용하도록 해야 합니다 .

관련 정보