2개의 명령이 포함된 스크립트를 테스트하고 있습니다 sed
. 첫 번째 명령은 입력에서 줄을 제거하고, 두 번째 명령은 입력 끝에 줄을 추가합니다.
$ cat input.txt
Line 1
Line 2
Line 3
$ sed '/Line 1/d;$aAppended line' input.txt
Line 2
Line 3
Appended line
$ sed '/Line 2/d;$aAppended line' input.txt
Line 1
Line 3
Appended line
여태까지는 그런대로 잘됐다. 그러나 삭제하기로 선택한 줄이 입력된 마지막 줄인 경우 스크립트의 두 번째 명령은 실행되지 않습니다.
$ sed '/Line 3/d;$aAppended line' input.txt
Line 1
Line 2
sed
입력 줄은 한 번에 읽혀지고 더 이상 읽을 줄이 없을 때까지 각 줄에서 스크립트가 "실행"되므로 내 스크립트가 결코 "완료"(즉, Appended line
추가되지 않음)된다는 사실이 의미가 있음을 배웠습니다 . .
그래도 이것은 나에게 문제가 됩니다(아직도 추가해야 합니다 Appended line
). 이 문제에 대해 잘 아는 사람이 있습니까? 그렇다면 "표준 해결 방법"이 있습니까? 내 생각에 대안(마지막 행을 제거한 다음 하나 추가)은 다음과 같습니다.바꾸다:
$ sed 's/Line 3/Appended line/' file.txt
Line 1
Line 2
Appended line
이것이 나의 유일한 선택인가?
답변1
d
매뉴얼 페이지의 명령 sed
:
패턴 공간을 삭제합니다.다음 사이클을 시작하세요.
여러 sed
명령이 제공된 순서대로 실행되므로 "다음 주기 시작"은 실제로 행이 삭제된 후 (현재 주기의) 삭제된 행에 적용될 수 있는 후속 명령 실행을 중지한다는 것을 의미합니다. 따라서 Line 3
마지막 행이고 삭제되면 새 루프가 시작되고a
미정마지막 줄에 적용되어야 할 명령은 실행되지 않습니다.
이 문제를 해결하려면 명령 순서를 반대로 하면 됩니다.
sed -e '$aAppended line' -e '/Line 3/d'
또는 GNU 특정 코드와 동등한 표준 코드:
sed '$a\
Appended line
/Line 3/d'
이렇게 하면 마지막 줄 뒤에 텍스트가 추가됩니다.앞으로 Line 3
제거됩니다(그리고 루프가 종료됩니다).
해당 a
줄은 추가되지 않습니다.공간을 패턴화하다;인용하다POSIX, 그것나중에 출력할 텍스트 예약, 텍스트[...]입력 라인을 얻으려는 다음 시도 전에 표준 출력에 기록되어야 합니다.d
[...], 따라서 해당 옵션의 영향을 받지 않습니다 -n
.
답변2
sed 옵션을 사용하면 -n
콘텐츠 삭제에서 콘텐츠 인쇄로 문제를 변경할 수 있습니다.
#!/usr/bin/sed -nf
/Line 3/!p
$aAppended line
이는 /text/!
부정입니다. 즉, 포함되지 않은 줄에만 일치합니다 text
. 그리고 p
나머지 스크립트의 실행을 중지해도 부작용이 없으며 새로운 루프가 발생하지 않습니다.
답변3
perl
다른 사람들은 이미 이런 일이 발생하는 이유를 설명했기 때문에 대신 이 문제가 없는 를 사용하는 다른 솔루션을 제공하겠습니다 sed
.
$ cat input.txt
Line 1
Line 2
Line 3
$ perl -lne 'print unless /Line 3/; END{print "Appended line"}' input.txt
Line 1
Line 2
Appended line
답변4
s, g 및 p(-n 포함) 이외의 sed 구성을 사용할 때마다 명확성, 견고성 및 이식성을 위해 awk(또 다른 필수 POSIX 텍스트 처리 도구)를 사용하는 것이 가장 좋습니다.
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ awk 'NR!=1; END{print "Appended line"}' input.txt
Line 2
Line 3
Appended line
$ awk 'NR!=2; END{print "Appended line"}' input.txt
Line 1
Line 3
Appended line
$ awk 'NR!=3; END{print "Appended line"}' input.txt
Line 1
Line 2
Appended line