나는 그것을 작동시킬 수 없다. GNU sed 문서는 파이프를 탈출한다고 말했지만 작동하지 않으며 탈출하지 않고 직선 파이프를 사용하지 않습니다. Parens를 추가해도 아무런 차이가 없습니다.
$ 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
답변
기본적으로sed
대체 연산자를 포함하지 않는 POSIX 기본 정규 표현식을 사용합니다 |
. sed
GNU 및 FreeBSD를 포함한 많은 버전은 확장을 포함하는 확장 정규 표현식 으로의 전환을 지원 |
합니다. 사용 방법은 다양합니다 : GNU sed는 사용-r
하고 FreeBSD , NetBSD , OpenBSD 및 OS X는 사용 -E
합니다. 다른 버전은 대부분 전혀 지원하지 않습니다. 당신이 사용할 수있는:
echo 'cat dog pear banana cat dog' | sed -E -e 's/cat|dog/Bear/g'
BSD 시스템 sed -r
과 GNU에서 작동합니다.
GNU sed
는 완전히 문서화되지 않았지만에 대한 작업을 지원하는 것으로 보이 -E
므로 위와 같이 다중 플랫폼 스크립트가있는 경우 이것이 최선의 선택입니다. 문서화되어 있지 않기 때문에 실제로는 신뢰할 수 없습니다.
의견에 따르면 BSD 버전 -r
은 문서화되지 않은 별칭으로도 지원 됩니다. OS X는 여전히 현재는 아니고 이전 NetBSD 및 OpenBSD 컴퓨터도 액세스 할 수 없지만 NetBSD 6.1은 그렇지 않습니다. 내가 보편적으로 도달 할 수있는 상업적 Unices는 그렇지 않습니다. 따라서 이식성 문제는이 시점에서 상당히 복잡해졌지만 간단한 대답은 필요할 때 전환awk
하는 것인데, 어디서나 ERE를 사용합니다.
답변
(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 사양의 다음 버전에있을 것입니다.
답변
이 작업을 수행하는보다 효율적인 방법은 주소를 사용하는 것입니다. 당신은 이것을 할 수 있습니다 :
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
이러한 방식으로 줄에 문자열 cat 이없고 문자열 dog 문자열 sed
b
이 스크립트에서 빠져 나오지 않으면 현재 줄을 자동 인쇄하고 다음 줄을 당겨 다음 사이클을 시작합니다. 따라서 다음 명령을 수행하지 않습니다.이 예 c
에서는 Bear 를 읽기 위해 전체 행을 걸지만 아무 것도 할 수 있습니다.
!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
에서 패턴 공간에 추가 된 공간을 유지하고 마지막에 방금 추가 한 줄 바꿈까지 줄의 시작 부분에서 모든 문자가 그 뒤에 공백으로 둘러싸인 문자열과 일치하는지 확인하십시오. 그렇다면 나는 전체 로트를 Bear로 교체하고 P
패턴 공간에서 처음 나타나는 개행 d
까지만 찢어 버리고 해를 끼치 지 않으면 해를 끼치 지 않습니다 .
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
그리고 내가 유연하다고 말할 때, 나는 그것을 의미합니다. 여기가 대체 고양이 와 BrownBear 와 개 에 BlackBear :
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
물론 룩업 테이블의 내용을 크게 확장 할 수 있습니다 . 90 년대에 Greg Ubben의 유즈넷 이메일에서 주제에 대한 아이디어를 얻었 습니다 sed s///
.
답변
이것은 매우 오래된 질문이지만 누군가가 시도하고 싶을 경우 sed 파일로 sed 에서이 작업을 수행하는 상당히 낮은 노력 방법이 있습니다. 각 옵션은 별도의 행에 나열 될 수 있으며 sed는 각 옵션을 평가합니다. 논리적으로 or와 같습니다. 예를 들어 특정 코드가 포함 된 줄을 제거하려면
당신은 말할 수 있습니다 : sed -E '/^\/\*!(40103|40101|40111).*\/;$/d'
또는 이것을 sed 파일에 넣으십시오.
/^\/\*!40103.*\/;$/d
/^\/\*!40101.*\/;$/d
/^\/\*!40111.*\/;$/d
답변
여기에 어떤 구현 특정 옵션을 사용하지 않는 기술이다 sed
(예를 들어 -E
, -r
). 패턴을 단일 정규식으로 설명하는 대신 cat|dog
간단히 sed
두 번 실행할 수 있습니다 .
echo 'cat
dog
pear
banana
cat
dog' | sed 's/cat/Bear/g' | sed 's/dog/Bear/g'
실제로 확실한 해결 방법이지만 공유 할 가치가 있습니다. 매우 긴 체인은보기에 sed
좋지 않지만 자연스럽게 두 개 이상의 패턴 문자열로 일반화됩니다 .
sed -i
파일을 변경하기 위해 종종 (모든 구현에서 동일하게 작동) 사용 합니다. 여기에는 각 임시 결과가 파일에 저장되므로 패턴 문자열의 긴 목록이 멋지게 통합 될 수 있습니다.
for pattern in cat dog owl; do
sed -i "s/${pattern}/Bear/g" myfile
done