하나의 정규식을 바꾼 다음 첫 번째 정규식과 일치하지 않는 모든 줄에서 두 번째 정규식을 바꿉니다.

하나의 정규식을 바꾼 다음 첫 번째 정규식과 일치하지 않는 모든 줄에서 두 번째 정규식을 바꿉니다.

예제 작업: 행에 가 포함되어 있으면 foo이를 로 바꾸고 bar, 그렇지 않으면 baz행에 추가합니다.

sed -e s/foo/bar/ -e s/$/baz/첫 번째 명령이 일치하는지 여부에 관계없이 두 번째 명령이 실행되므로 작동하지 않습니다. sed게임이 끝난 후 다음 줄로 이동하도록 게임에 지시할 수 있는 방법이 있나요 ?

답변1

t성공적인 교체 후 다음 주기를 시작하려면 레이블 없이 명령을 사용할 수 있습니다.

$ cat ip.txt 
a foo 123
xyz
fore
1foo

$ sed -e 's/foo/bar/' -e t -e 's/$/baz/' ip.txt
a bar 123
xyzbaz
forebaz
1bar

매뉴얼에서:

t 태그(테스트)

마지막 입력 줄을 읽거나 조건 분기를 수행한 이후 교체가 성공한 경우에만 레이블로 분기합니다. 라벨을 생략할 수 있으며, 이 경우 다음 사이클이 시작됩니다.

답변2

더 강력한 방법awk스크립트:

awk '{ if (/foo/) gsub(/foo/, "bar"); else $0 = $0 "baz" }1' file

또는 더 짧게:

awk '{ if (!gsub(/foo/, "bar")) $0 = $0 "baz"; }1' file

답변3

이 시도:

sed -e '/foo/!s/$/baz/g' -e s/foo/bar/g

답변4

그것을 알아 냈습니다 :

sed -e '/foo/{s//bar/;p;D};s/$/baz/' 

설명하다:

  • 다음을 사용하여 여러 sed 명령을 연결 ;하고 그룹화 할 수 있습니다.{}
  • /foo/이 패턴을 포함하는 모든 행을 선택합니다 foo.
  • s//bar/s/foo/bar/동일함 - 빈 패턴은 마지막 검색을 반복한다는 의미입니다(이 경우) foo.
  • p인쇄 패턴 공간(교체된 선)을 나타냅니다.
  • D현재 줄을 지우고 다음 줄로 이동한다는 의미입니다.
  • s/$/baz/baz전달해야 할 줄을 이전 규칙에 추가하는 작업의 두 번째 부분을 수행합니다 .

관련 정보