grep에 이중 백슬래시가 필요한 이유는 무엇입니까?

grep에 이중 백슬래시가 필요한 이유는 무엇입니까?

특수 문자가 특별한 동작을 생성한다는 것을 알고 있습니다.

$ echo 'abc[abc' | grep -o '['
grep: Invalid regular expression

작은따옴표는 쉘 해석이나 소스 문자열 변경과 관련된 문제를 방지합니다.

또한 이러한 특수 문자의 특별한 해석을 피하려면 백슬래시가 필요하다는 것도 알고 있습니다.

$ echo abc[abc | grep -o '\['
[

백슬래시-specialChar( \[)를 일치시키려면 grep에 더 많은 백슬래시가 필요합니다.

$ echo 'abc\[abc' | grep -o '\\\['
\[

그러나 an과 같은 간단한 문자는 특별하지 않으며 fa와 일치하는 데 \f필요하지 않습니다 .추가의탈출하다:

$ echo 'abc\fabc' | grep -o '\f'
f

그러나 그것은 그렇습니다:

$ echo 'abc\fabc' | grep -o '\\f'
\f

단어다음과 같은 문자열:

$ echo 'abc\fabc' | grep -F -o '\f'
\f

가서 \fgrep이 어떻게든 설명한다는 것을 증명해 보세요.

이것수동상태:

'\' 문자는 뒤에 특정 일반 문자가 올 때 특별한 의미를 갖습니다.
/s는
'[[:space:]]'와 동의어인 공백과 일치합니다.

certain ordinary characters다른 사람도 있다는 암시보통 사람들목록에 없고 그렇지 않습니다.특별한상태.

따라서 내 이해는 a \f(단 하나의 문자만 선택)가 소스 문자열과 일치해야 한다는 것입니다 \f.

내가 무엇을 놓치고 있나요?

관련된:

1-grep: 후행 백슬래시.

2-grep의 이스케이프 슬래시 "\".

삼-sed에 일반 백슬래시를 나타내기 위해 3개의 백슬래시가 필요한 이유는 무엇입니까?.

답변1

그러나 f와 같은 간단한 문자는 특별하지 않으며 \f와 일치시키기 위해 추가 이스케이프가 필요하지 않습니다.

$ echo 'abc\fabc' | grep -o '\f'
f

f특별하지는 않지만 백슬래시는 정규식에서 특별합니다. 일반 문자 앞에 오는 백슬래시의 동작은 백슬래시 이스케이프를 구현하는 유틸리티마다 다르지만 다음과 같습니다.POSIX 정규식의 경우 정의는 다음과 같습니다.:

이스케이프되지 않은 문자( '\' )가 앞에 있는 일반 문자의 해석은 다음과 같습니다.명확하지 않다, 다음 경우는 제외: [ (){}, 괄호 안의 표현식 중 하나 1]9

마찬가지로 확장 정규 표현식에서는 다음과 같습니다.

일반 문자는 ERE 특수 문자에 나열된 ERE 특수 문자를 제외하고 지원되는 문자 세트의 모든 문자입니다. 이스케이프 처리되지 않은( ) 앞에 오는 일반 문자의 해석은 \\대괄호 표현식의 컨텍스트를 제외하고는 정의되지 않습니다(ERE 대괄호 표현식 참조).

grep(또는 이것이 사용하는 정규식 구현)은 단순히 \fwith 로 해석되도록 선택합니다 f. 백슬래시가 f(특수 속성이 없더라도) 의 특수 속성을 제거한다고 생각할 수도 있습니다. 백슬래시는 ERE에서도 같은 방식으로 작동합니다. 또는 임의의 결정으로.


이것리눅스 매뉴얼 페이지regex(7)명시적인 설명:

원자는 [무엇보다도] a \뒤에 다른 문자(!)가 옵니다(해당 문자가 존재하지 않는 것처럼 일반 문자와 일치합니다 \(!)).

내 Mac에서는 C 스타일 이스케이프 문자와 마찬가지로 폼 피드 문자를 grep나타냅니다 . \f따라서 printf '\f' | grep '\f'일치하면 둘 다 이를 페이지 피드로 해석합니다( printf이를 수행하도록 정의됨).

답변2

내가 무엇을 놓치고 있나요?

grep 문자열에 관한 한 f이는 정규 표현식의 일반 문자이므로 '\f'다음과 같습니다 'f'.

$ echo 'abc\fabc' 
abc\fabc
$ echo 'abc\fabc' | grep -o '\f'
f
$ echo 'abc\fabc' | grep -o 'f'
f

그러나 f와 같은 간단한 문자는 특별하지 않으며 이스케이프할 필요가 없습니다.

$ echo 'abc\fabc' | grep -o '\f'

f

그러나 그것은 그렇습니다:

$ echo 'abc\fabc' | grep -o '\\f'

\f

아니요, 그렇지 않습니다. 이전 예를 되돌아보면 다음과 같습니다.

$ echo 'abc\fabc' | grep -o 'f'
f

매뉴얼 페이지re_format(7)레코드 regexp는 \fregexp와 동일합니다 f.

... '\' 다음에 다른 문자가 옵니다('\'가 없는 것처럼 일반 문자로 처리되는 문자와 일치) ...

관련 정보