sed를 사용하여 첫 번째 줄부터 마지막 ​​패턴이 포함된 줄까지 인쇄하시겠습니까?

sed를 사용하여 첫 번째 줄부터 마지막 ​​패턴이 포함된 줄까지 인쇄하시겠습니까?

다음 명령은 특정 패턴의 첫 번째 발생까지 인쇄하지만 이후 발생은 포함하지 않는다는 것을 알고 있습니다.

sed -n '1,/<pattern>/p' <file>

sed '/<pattern>/q' <file>

예를 들어, 다음 줄이 포함된 파일이 있다고 가정해 보겠습니다.

this is a cow   
this is a goat  
this is a some fish  
this is a fishie  
this is a fish  
this is a lion  
this is a cat

이제 다음을 출력합니다.

$ sed '/fish/q' file  

this is a cow  
this is a goat  
this is a some fish 

$ sed -n '1,/fish/p' file  

this is a cow  
this is a goat  
this is a some fish 

첫 번째 줄부터 마지막 ​​항목이 포함된 줄까지 출력을 시작하고 싶습니다.물고기즉, 내가 원하는 출력은 다음과 같습니다.

this is a cow   
this is a goat  
this is a some fish  
this is a fishie  
this is a fish 

달성하기 위해 사용하는 방법은 무엇입니까 sed?

답변1

이 시도:

$ tac infile | sed -n '/fish/,$p' |tac

일반적으로 sed 명령으로 실행하면 첫 번째 일치 패턴부터 입력 파일 끝까지 모든 행을 가져옵니다.

$ sed -n '/fish/,$p' file

this is a some fish
this is a fishie
this is a fish
this is a lion
this is a cat

그래서 내 해결책은 다음과 같습니다. tac입력 파일에서 명령을 실행하면 마지막으로 일치하는 패턴이 첫 번째 패턴으로 변경됩니다. 결과 보기 tac infile:

$ tac infile

this is a cat
this is a lion
this is a fish
this is a fishie
this is a some fish
this is a goat
this is a cow

tac명령은 명령과 동일 cat하지만 tac파일을 역순으로 인쇄합니다.

이제 첫 번째 sed 명령을 실행하면 먼저 입력 파일의 끝까지 패턴과 일치하는 모든 줄을 얻게 됩니다. 좋다:

$ tac infile | sed -n '/fish/,$p'
this is a fish
this is a fishie
this is a some fish
this is a goat
this is a cow

좋아. 끝났어. tac줄을 원래 순서로 복원하려면 명령을 다시 실행 하면 됩니다 .

$ tac infile | sed -n '/fish/,$p' |tac
this is a cow
this is a goat
this is a some fish
this is a fishie
this is a fish

완벽한!

답변2

sed이는 매우 간단합니다. 단지 두 버퍼 간에 약간의 조정이 필요합니다. 예를 들어:

sed -n 'H;/fish/!d;$!n;x;p;G
' <<\INFILE
this is a cow
this is a goat
this is a some fish
this is a fishie
this is a fish
this is a lion
this is a cat
INFILE

이 명령은 H삽입된 줄 문자 뒤의 기존 공백 에 각 줄을 추가합니다 \n. 일치 !하지 않는 행은 출력에서 /fish/​​즉시 제거됩니다 . 이것은 우리에게 선만 d남깁니다 . /fish/따라서 이 줄은 n입력된 확장 줄로 덮어쓰여집니다. 그런 다음 패턴과 h기존 공간이 교체됩니다. H결국 우리는 라인을 낡게 만들었습니다. 이제 패턴 공간은 H이전 공간이고 그 반대도 마찬가지입니다. 따라서 마지막 행이 일치할 때 저장된 내용을 p인쇄합니다 ./fish/

p일치 항목이 발견된 경우에만 인쇄하고 그 사이에 중간 행을 저장하므로 일치 항목이 마지막으로 발생한 경우에만 도달합니다. 하지만 일치하는 항목 사이에는 가능한 한 적은 양만 저장합니다. x버퍼가 변경될 때마다 플러시됩니다. 결과는 다음과 같습니다.

this is a cow   
this is a goat  
this is a some fish  
this is a fishie  
this is a fish

내가 가끔 생선을 건너뛰는 것을 알려준 Don Christy에게 큰 감사를 드립니다. 이제 만약을 대비해 플러시할 때마다 버퍼가 양쪽 끝에 푸시되고 현재 패턴 공간을 삭제하기 전에 매번 덮어쓰게 됩니다. 그것은 첫 번째나 마지막 줄의 물고기와 내가 아는 한 그 사이의 모든 줄에 적용됩니다.

제가 하고 있는 또 다른 일은 n마지막 줄의 연장 코드를 당기는 것입니다. 이는 절대 금기 sed사항입니다. 이 일을 도와준 Don에게 다시 한 번 감사드립니다.

더 철저한 예:

sed 'x;/./G;//!x;/fish/p;//s/.*//;x;d'

이것이 다른 문제를 더 잘 해결하기를 바랍니다. h패턴/기존 공백은 매 사이클마다 변경됩니다. 이는 명령 끝에서 편집 대체로 인해 추가 빈 줄이 발생하는 것을 x방지하기 위한 것입니다 . s///따라서 버퍼가 교체되고 버퍼가 비어 있지 않은 상태로 유지되면 현재 줄이 여기에 추가되고 그 뒤에 \newline 문자가 추가됩니다. 그렇지 않으면 추가 줄이 버퍼에서 나옵니다. 그렇지 않으면 버퍼가 다시 교체되고 h이전 공간은 현재 주기 동안 비어 있게 유지됩니다. 내가 아는 한, 이 명령은 모든 빈 줄과 그 밖의 모든 것을 유지하지만 마지막 일치 항목에서 인쇄를 중지합니다.

내가 겪은 어려움 중 일부는 h일반적으로 기존 공간에서 발생합니다. 이를 효과적으로 사용하는 유일한 방법은 기존 라인과 비교하기 위해 라인 사이클 아래 - 뒤 -에 있는 것입니다. 내가 평소에 선호하는 것은 looping 입니다 N;P;D. 아마도 다음과 같은 것을 사용하여 이 작업을 수행할 수 있을 것입니다.

sed -ne :n -e '/fish/!N;//p;//!bn'

입력 확장 라인을 패턴 공간에 지속적으로 sed추가 하고 레이블 로 돌아가서 재시도합니다.Nb:n물고기현재까지 설정된 어떤 라인과도 일치하지 않습니다. 라인 사이클의 끝에서 내용을 덤프하고 새 버퍼로 다시 시작하기 전에 일치하는 p라인 또는 라인 시퀀스 만 인쇄합니다.fish

여기서는 의도적으로 마지막 줄을 테스트하지 않습니다. 마지막 줄이 일치하면 인쇄됩니다. 그렇지 않으면 -nGNU의 경우 에도 sed루프가 파일의 마지막 줄을 모두 종료할지 여부를 결정합니다.

답변3

Sed보다 짧은 awk를 사용할 수도 있습니다.

awk ' /^fish/ { print $0 }' filename.txt

어떤 사람들은 다음과 같이 쓸 수도 있습니다:

awk ' /^fish/ { print $1 $2 $3 $4 $5 }' filename.txt

$n열을 나타냅니다 . 바로가기는 $0전체 행을 나타냅니다.

답변4

Raku(이전 Perl_6) 사용

raku -e '$/.put if m/^ .* fish/ for lines.join("\n");'

입력 예:

this is a cow   
this is a goat  
this is a some fish  
this is a fishie  
this is a fish  
this is a lion  
this is a cat

예제 출력:

this is a cow   
this is a goat  
this is a some fish  
this is a fishie  
this is a fish

위의 정규 표현식은 한 단어에서 종료되며 해당 단어가 줄의 마지막 단어 fish인 한 fish제대로 작동합니다 . 그러나 OP가 전체를 캡처하려는 경우마지막 줄(예: fisherman전체 단어 반환) 위의 정규식 일치자를 로 변경합니다 m/^ .* fish .*? $$ /.

https://raku.org

관련 정보