예제 작업: 행에 가 포함되어 있으면 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
전달해야 할 줄을 이전 규칙에 추가하는 작업의 두 번째 부분을 수행합니다 .