sed의 정규 표현식에서 [\ w] +를 사용하는 방법은 무엇입니까?


24

나는 Windows에 있지만 내 질문은 여전히 ​​여기에 올바르게 배치되어있는 것 같습니다.

C:\Users\User>grep --version
GNU grep 2.6.3

C:\Users\User>sed --version
GNU sed version 4.2.1

나는 다음과 같은 작업 (출력 here)을 발견했습니다 .

echo here | grep -E "\w+"
echo here | grep -E "[her]+"

그러나 이것은 작동하지 않습니다 (아무것도 출력하지 않음).

echo here | grep -E "[\w]+"

이것은 다시 (출력 here)합니다 :

echo here | grep -P "[\w]+"

따라서 [\w]Perl 정규 표현식에만 해당되는 것으로 가정합니다. 그 맞습니까?

그럼 이야기합시다 sed. 이것은 작동합니다 (출력 gone) :

echo here | sed -r "s/\w+/gone/"
echo here | sed -r "s/[her]+/gone/"

그리고 다시, 이것은 (출력 here) 하지 않습니다 :

echo here | sed -r "s/[\w]+/gone/"

이제 sed에 대해 Perl 정규 표현식을 활성화하는 방법은 무엇입니까?

답변:


11

툴과 버전이 다르면 정규 표현식의 변형을 지원합니다. 각각의 문서는 그들이 무엇을 지원하는지 알려줄 것입니다.

표준은 모든 적합한 응용 프로그램에서 사용할 수있는 최소 기능 세트에 의존 할 수 있도록 존재합니다.

예를 들어, POSIX에서 지정한 기본 정규식 의 모든 최신 구현 sedgrep구현 (최소 한 버전 또는 표준의 다른 버전이지만 해당 표준은 지난 수십 년 동안 그 점에서 크게 발전하지 않았습니다).

POSIX BRE 및 ERE에는 [:alnum:]문자 클래스가 있습니다. 이는 로케일의 문자와 숫자와 일치 a-zA-Z0-9합니다 (로케일이 C가 아닌 경우 보다 더 많이 포함됨 ).

그래서:

grep -x '[[:alnum:]_]\{1,\}'

하나 이상의 숫자 또는 _와 일치합니다.

[\w]POSIX는 백 슬래시 또는와 일치해야합니다 w. 따라서 비표준 옵션을 사용하지 않는 한 가능한 경우 grep또는 sed구현을 찾을 수 없습니다 .

\wPOSIX는 단독으로 동작을 지정하지 않으므로 구현은 원하는 것을 수행 할 수 있습니다. GNU grep는 그것을 오래 전에 추가했습니다.

GNU grep는 자체 정규식 엔진을 가지고 있었지만 이제는 GNU libc 엔진을 사용합니다 (자체 사본이 포함되어 있음).

로케일의 숫자와 밑줄을 일치시키기위한 것입니다. 그러나 현재 1 바이트 문자 만 일치한다는 버그가 있습니다 (예 : UTF-8 로케일은 분명히 문자이지만 é가 단일 인 모든 로케일에서 é와 일치하더라도 캐릭터).

\wperl regexp와 PCRE 에도 regexp 연산자 가 있습니다 . PCRE / perl은 POSIX 정규식이 아니며, 또 다른 것입니다.

이제 GNU grep -P가 PCRE를 사용 하는 방식에 따라 without와 같은 문제가 발생합니다 -P. (*UCP)(UTF8이 아닌 로케일에서도 부작용 이 있지만) 사용하여 해결할 수 있습니다 .

GNU sed는 또한 자체 정규 표현식으로 GNU libc의 정규 표현식을 사용합니다. GNU와 같은 버그가없는 방식으로 사용합니다 grep.

GNU sed는 PCRE를 지원하지 않습니다. 코드에 이전에 시도 된 증거가 있지만 더 이상 의제로 보이지 않는 것 같습니다.

Perl의 정규 표현식을 원한다면 사용하십시오 perl.

그렇지 않으면, 내가의 특정 구현의 가짜 비표준 기능에 의존하는 것보다 오히려 그런 말 것 sed/ grep그것은 표준 및 사용과 스틱에 더 좋을 것이다 [_[:alnum:]].


[_[:alnum:]][\w/]( [_[:alnum:]/]이 경우) 처럼 확장 할 수있는 좋은 해결 방법입니다 .
bers

1
이 답변은 GNU의 한계와 관련하여 구식입니다 grep.
Stéphane Chazelas

7

당신은 맞습니다 \w-PCRE의 일부입니다-perl 호환 정규 표현식. 그러나 '표준'정규식의 일부는 아닙니다. http://www.regular-expressions.info/posix.html

일부 버전에서는 sed지원할 수 있지만 가장 쉬운 방법은 플래그 를 지정하여 모드 perl에서 사용 sed하는 것 -p입니다. (와 함께 -e). (자세한 내용은 perlrun)

그러나 당신은 []그 예에서 그 주위를 필요로하지 않습니다 -그것은 유효한 물건 그룹을위한 것입니다.

echo here  | perl -pe 's/\w+/gone/'

또는 Windows의 경우 :

C:\>echo here  | perl -pe "s/\w+/gone/"
gone
C:\>echo here  | perl -pe "s/[\w\/]+/gone/"
gone

perlre더 많은 PCRE 자료를 참조하십시오 .

여기에서 perl을 얻을 수 있습니다 : http://www.activestate.com/activeperl/downloads


내 질문 \w과 의 차이점에 유의하십시오 [\w]. 어떤 명령이 작동하고 어떤 명령이 작동하지 않는지 명확히하기 위해 각 명령의 출력으로 업데이트합니다. 특히, sed이해 \w하지만 이해 하지는 않습니다 [\w]. 또한 예를 들어 [\w]사용하고 싶기 때문에 일 해야 합니다 [\w/].
bers

어떤 경우에는 인용 문제 일 수 있습니다. 어느 쪽이든- perl할 수 있습니다 :).
Sobrique

감사! Stéphane Chazelas의 대답은 내가 요청한 것에 조금 더 가깝습니다 (Perl이 설치되어 있지 않기 때문에-du * b Windows 사용자이므로 추측합니다).
bers

괜찮습니다-Windows에 Perl을 설치하는 것이 좋습니다. 그것은 내 첫 번째 일 중 하나이며 매우 도움이됩니다.
Sobrique

\w펄에 들어가기 전에 GNU grep (80 년대)에 있었고 GNU emacs에 있었을 수도 있습니다.
Stéphane Chazelas

1

를 적용 할시기와 확장시기를 다르게 결정 grep하고 있다고 생각 합니다 . 펄에서 정규 표현식 은 모든 단어 문자를 의미 하며 그룹 내의 문자를 일치로 적용하도록 정의합니다. 앞에 "확장"하면 모든 단어 문자의 문자 클래스가됩니다. 대신 당신이 경우에 먼저 두 개의 문자로 문자 클래스가됩니다 하고 그래서 하나 이상의 두 문자가 포함 된 패턴과 일치하는 것입니다.sed[]\w\w[]\w[][]\w

그래서 그 보인다 sed을보고있다 []가 일치하는 정확한 문자를 포함하는 대신 특별한 순서를 존중로 치료 \wperlgrep않습니다. 물론, []이 예제에서는 완전히 불필요하지만, 중요한 경우를 상상할 수 있지만 Parens 및 Ors로 작동하도록 만들 수 있습니다.


그렇게된다면 놀랐습니다. \ 이스케이프 코드이며 구분 기호를 이스케이프 처리하는 데 사용합니다. 본질적으로 그것은 다른 것보다 우선 순위가 높아야 함을 의미합니다. 나는 때문에이 구현되지 있다는 가능성을 생각 \w정규 표현식 사양의 일부가 아닙니다
Sobrique

글쎄, 경험적으로 그것은 나를 위해 gnu sed를 사용하는 경우 인 것 같습니다 : 마치 그것이 각각의 w와 일치 하고 대체를 하는 것처럼 echo whe\\ere | sed -r 's/[\w]+/gone/g나에게줍니다gonehegoneere` and
Eric Renouf

Eric Renouf가보고있는 것을 확인할 수 있습니다. 어떻게 든 백 슬래시를 제거하고 싶습니까? :)
bers

나는 그것이 정답이라고 생각하지 않습니다. Sed는 다른 유형의 문자 클래스 정의 혼합을 지원하지 않으므로 두 유형의 문자 클래스를 모두 사용해야하는 경우 다른 도구를 선택하거나 sed를 선택하는 경우 지원하는 구문을 사용하는 경우
Eric Renouf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.