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에서 지정한 기본 정규식 의 모든 최신 구현 sed및 grep구현 (최소 한 버전 또는 표준의 다른 버전이지만 해당 표준은 지난 수십 년 동안 그 점에서 크게 발전하지 않았습니다).

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을보고있다 []가 일치하는 정확한 문자를 포함하는 대신 특별한 순서를 존중로 치료 \w로 perl및 grep않습니다. 물론, []이 예제에서는 완전히 불필요하지만, 중요한 경우를 상상할 수 있지만 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.