정규식 문자를 정규식 문자로 해석하기 위해 sed에서 정규식 문자를 이스케이프 처리해야 하는 이유는 무엇입니까?

정규식 문자를 정규식 문자로 해석하기 위해 sed에서 정규식 문자를 이스케이프 처리해야 하는 이유는 무엇입니까?


cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
내가 보기엔~ 해야 하다정규식을 구성하려면 문자를 이스케이프하세요. 이 경우 여러 번 해석하려면 중괄호를 이스케이프 처리해야 합니다.
왜? 이스케이프하지 않는 한 모든 것이 정규식 문자가 될 것이라고 생각했습니다. 그것은 그 반대입니다.

답변1

sed사용하기 때문이에요POSIX BRE(Essential 정규 표현식), Perl이나 친구들에게서 익숙할 수 있는 ERE(확장 정규 표현식)가 아닙니다.

sed(1)매뉴얼 페이지 에서 :

REGULAR EXPRESSIONS
       POSIX.2 BREs should be supported, but they aren't completely because of
       performance problems.  The \n sequence in a regular expression  matches
       the newline character, and similarly for \a, \t, and other sequences.

관련 인용문은 위 링크에서 나옵니다:

기본 정규식 또는 BRE 스타일은 기존 UNIX grep 명령에서 사용되는 것과 유사한 스타일을 표준화합니다. 이것은 오늘날에도 여전히 사용되고 있는 정규식의 가장 오래된 스타일입니다. 이 스타일을 독특하게 만드는 것은 대부분의 메타 문자에 스타일을 부여하기 위해 백슬래시가 필요하다는 것입니다. POSIX ERE를 포함한 대부분의 다른 스타일은 백슬래시를 사용하여 메타 문자의 의미를 억제합니다.

에서 문자 그대로 인용함크레이그 손더스의 댓글:

적어도 GNU sed에서는 -r 또는 --regexp-extended 명령줄 옵션을 통해 확장 정규식을 사용하도록 sed에 지시할 수 있습니다. 이는 과도한 이스케이프를 통해 sed 스크립트를 보기 흉하게 만드는 것을 방지하려는 경우에 유용합니다.

답변2

여기에는 역사적인 이유가 있습니다.

edRegexp는 1970년대 초에 Unix 유틸리티로 처음 소개되었습니다. 동일한 작성자의 구현을 ed기반으로 하지만 qed사람들은 더 복잡한 정규식을 이해할 수 없으며 위의 모든 상황을 벗어나는 , , 및 이해 만 할 수 ed있습니다 .^$[...].*\

이제 더 많은 연산자가 필요할 때 이전 버전과의 호환성을 유지하면서 이를 도입할 수 있는 방법을 찾아야 합니다. 의 모든 인스턴스를 s ed바꾸기 위해 as 명령을 사용하는 데 사용되는 스크립트에서 or 연산자를 도입하면 스크립트가 중단됩니다.s/foo() {/foo (var) {/gfoo() {foo(var) {({

그러나 어떤 스크립트 s/foo\(\) {/foo\(var\) {/도 와 동일하므로 이를 수행할 수 없으며 RE 연산자가 아니므로 s/foo() {/foo(var) {/이스케이프할 이유가 없습니다 . (따라서 new \(or \{연산자를 도입해도 이전 구문을 사용하는 기존 스크립트가 중단될 가능성이 없으므로 이전 버전과의 호환성이 중단되지 않습니다.

그래서 이것이 이루어졌습니다. 나중에 처음에는 유사한 작업을 수행하는 명령 \(...\)을 위해 추가되었지만 나중에는 (그러나 여전히 유사한 작업은 아님 ) 추가되었습니다 .s eds/foo\(.\)/\1bar/grep '\(.\)\1'\(xx\)*

egrep거의 10년 후인 UnixV7(1979)에서는 확장 정규식 이라고 불리는 새로운 유틸리티에 새로운 형태의 정규식이 추가되었습니다 awk(이들은 새로운 도구이기 때문에 이전 버전과의 호환성을 깨지 않았습니다). 마지막으로 Ken Thompson의 고대 기능 qed(교체 연산자 |, 그룹화 ) 을 제공하고 및 (..)*같은 일부 연산자를 추가합니다 (그러나 기본 정규 표현식의 역참조 기능은 없음).+?

나중에 BSD는 \<and \>(BRE와 ERE 모두에)를 추가한 반면 SysV는 \{and를 \}BRE에만 추가했습니다.

훨씬 나중에까지 ERE에 추가 {되지 않아 }이전 버전과의 호환성이 손상되었습니다. 모두가 추가한 것은 아닙니다. 예를 들어, GNU는 POSIX 적합성 모드로 강제 전환하지 않는 한 awk버전 4.0.0(2011)까지 이를 지원하지 않았습니다 .{

GNU는 90년대 초반에 작성되었을 때 BSD와 SysV(예: , ) grep의 모든 장점을 추가했으며 BRE와 ERE에 대해 두 개의 별도 정규식 구문과 엔진을 제공하는 대신 유일한 BRE 대응 연산자인 두 연산자에서 동일하게 구현했습니다 . , , 앞에는 백슬래시가 와야 합니다(다른 BRE 구현과의 호환성을 위해). 그렇기 때문에 GNU에서 이를 수행 할 수 있고 (비록 POSIX가 아니거나 다른 구현에서 지원되지 않더라도) GNU에서 수행 할 수 있습니다 (POSIX가 아니거나 GNU를 포함한 다른 많은 구현에서 지원되지 않더라도 ).\<{(?{+.\+grep(.)\1egrepawk

연산자를 추가하는 것이 \x이전 버전과 호환되는 방식으로 더 많은 연산자를 추가하는 유일한 방법은 아닙니다. 예를 들어, 를 perl사용하는 것은 ERE에서 유효하지 않기 (?...)때문에 여전히 ERE와 호환됩니다 . 유사한 연산자의 경우 등 을 도입하여 다른 접근 방식을 취합니다.(?=...).*?vim\@=.\{-}

관련 정보