GNU 또는 BSD Sed의 정규식 대체/또는 연산자(foo|bar)

GNU 또는 BSD Sed의 정규식 대체/또는 연산자(foo|bar)

나는 그것을 작동시킬 수없는 것 같습니다. GNU sed 문서에는 파이프를 탈출하라고 나와 있지만 그것은 작동하지 않으며 탈출하지 않고 직선 파이프를 사용하는 것도 아닙니다. 괄호를 추가해도 아무런 차이가 없습니다.

$ echo 'cat
dog
pear
banana
cat
dog' | sed 's/cat|dog/Bear/g'
cat
dog
pear
banana
cat
dog

$ echo 'cat
dog
pear
banana
cat
dog' | sed 's/cat\|dog/Bear/g'
cat
dog
pear
banana
cat
dog

답변1

기본적으로sed사용POSIX 기본 정규식|, 교대 연산자 는 포함되지 않습니다 . 이것을 사용하도록 전환할 수 있습니다.확장 정규식, 여기에는 (또는 일부 구현의 일부 이전 버전에서) |교대 하는 것이 포함됩니다 . 당신은 그것을 사용할 수 있습니다 :-E-r

echo 'cat dog pear banana cat dog' | sed -E -e 's/cat|dog/Bear/g'

그리고 호환되는 시스템에서 실행됩니다. ( -e선택적으로 sed 스크립트 자체를 표시합니다. 생략할 수 있으며 특정 유형의 오류만 방지할 뿐입니다.)

아주 오래된 seds로 포팅하는 것은 복잡하지만 다음과 같은 작업도 가능합니다.로 전환awk필요한 경우 어디에서나 ERE를 사용합니다.

답변2

(a|b)이는 기본 정규 표현식이 아닌 확장 정규 표현식이기 때문에 발생합니다 . -E이를 처리하려면 옵션을 사용하십시오 .

echo 'cat
dog
pear
banana
cat
dog'|sed -E 's/cat|dog/Bear/g'

sed매뉴얼 페이지 에서 :

 -E      Interpret regular expressions as extended (modern) regular
         expressions rather than basic regular expressions (BRE's).

이는 -r동일한 신호이지만 -E이식성이 더 뛰어나며 POSIX 사양의 다음 버전에도 나타날 수 있다는 점에 유의하세요.

답변3

이를 수행하는 이식 가능한 방법(그리고 더 효율적인 방법)은 주소를 사용하는 것입니다. 다음을 수행할 수 있습니다.

printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '}' -e 'c\
Bear'

이 방법으로 줄에 문자열이 없으면고양이문자열을 포함하지 않습니다. sed b스크립트를 종료하고 현재 줄을 자동으로 인쇄하고 다음 줄을 가져와 다음 루프를 시작합니다. 따라서 다음 명령어를 실행하지 않습니다. 이 경우 c전체 라인을 읽기 위해 일시 ​​중지됩니다.하지만 그것은 무엇이든 할 수 있습니다.

또한 !b명령 sed의 모든 명령문 이오직dog문자열을 포함하는 행과 일치합니다 cat. 따라서 문자열을 포함하지 않는 행과 일치할 위험 없이 추가 테스트를 수행할 수 있습니다. 즉, 이제 규칙을 둘 중 하나에만 적용할 수도 있습니다.

그러나 그것이 다음에 오는 것입니다. 위 명령의 출력은 다음과 같습니다.

###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear

역참조를 사용하여 조회 테이블을 이식 가능하게 구현할 수도 있습니다.

printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x;}
G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'

이 간단한 예제 사례의 경우 설정 작업이 조금 더 필요하지만 sed장기적으로 보면 스크립트가 더 유연해집니다.

첫 번째 줄에서 x예약된 공간과 패턴 공간을 변경한 다음 문자열을 삽입합니다.<space><space>고양이와 개<space>예약된 공간으로 이동한 다음 x다시 변경하세요.

그 시점부터 그리고 이어지는 모든 줄에서 G패턴 공간에 공백을 추가한 다음 줄의 시작 부분부터 끝에 추가한 줄 바꿈까지의 모든 문자가 공백으로 둘러싸인 다음 문자열과 일치하는지 확인합니다. 그렇다면 전체 배치를 다음으로 교체합니다.그렇지 않다면 아무런 해를 끼치지 않습니다. P패턴 공간에서 개행 문자의 첫 번째 항목을 인쇄한 다음 d모두 제거하기 때문입니다.

###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear

제가 유연하다고 말하는 것은 진심입니다. 여기서 교체 중입니다고양이그리고갈색 곰그리고그리고흑곰:

printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x;}
     G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'

###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear

물론 조회 테이블의 내용을 상당히 확장할 수 있습니다.그렉 우벤sed s///1990년대에 그는 단일 명령문으로 대략적인 계산기를 구성하는 방법을 설명했습니다 .

답변4

이것은 상당히 오래된 질문이지만 누군가가 그것을 시도하고 싶다면 sed 내의 sed 파일을 사용하여 이 작업을 수행하는 상당히 쉬운 방법이 있습니다. 각 옵션은 별도의 줄에 나열될 수 있으며 sed는 각 옵션을 평가합니다. 이는 or와 논리적으로 동일합니다. 예를 들어 특정 코드가 포함된 줄을 삭제하려면 다음을 수행하세요.

당신은 말할 수 있습니다 :sed -E '/^\/\*!(40103|40101|40111).*\/;$/d'

아니면 이것을 sed 파일에 넣으세요:

/^\/\*!40103.*\/;$/d
/^\/\*!40101.*\/;$/d
/^\/\*!40111.*\/;$/d

관련 정보