한 줄에서 n번째 패턴 발생을 인쇄합니다(포함).

한 줄에서 n번째 패턴 발생을 인쇄합니다(포함).

여러 행이 있다고 가정 해 봅시다비슷한아래 파일에 넣습니다.

Turbo is a cat. cats are good. cats are not dog.
Coco is a black cat. cats are furry. cats are not dog.

이제 단어가 처음으로(또는 n번째) 나타날 때까지 구체적으로 캡처하려는 grep경우 . 원하는 출력:^.*catcat

Turbo is a cat
Coco is a black cat
*blah is a so and so cat*

어떻게 할 수 있니 grep?

grep추신: 저는 only(또는 다른 변형)를 사용하여 답변을 얻고 싶습니다 .

^.*cat.추신: 나는 grep을 하고 삭제하기 위해 아무것도 하고 싶지 않습니다."." . 일반적인 답변을 원합니다.

답변1

그리고POSIX grep, 전체 줄을 인쇄하거나 줄 내용을 전혀 인쇄하지 않도록 선택할 수 있습니다. 이 줄을 변환하려면 sed 또는 awk와 같은 다른 도구를 사용해야 합니다. 첫 번째 항목까지 인쇄하려면 다음을 수행하십시오 cat.

sed -n 's/cat.*/cat/'
awk 'sub(/cat.*/,"")'

대부분의 인쇄질소발생하는 상황은 더욱 복잡합니다.

sed -n 's/cat/&\
/3; T; P'
awk 'gsub(/cat/,"&\n") >= 3 {split($0, a, "\n"); printf "%s%s%s\n", a[1], a[2], a[3]}'

그리고GNU grep, 이 -o옵션을 사용하여 행의 일치하는 부분만 인쇄할 수 있습니다. -P다음 옵션을 사용하여 Perl 구문을 활성화합니다.탐욕스럽지 않은 수량자사용 가능.

grep -P -o '^(.*?cat){1}'

중괄호 안의 숫자를 실제 숫자로 바꾸세요.Ncat인쇄할 마지막 항목의 위치입니다.

확장 정규식( -E)을 사용하여 동일한 내용을 표현할 수 있지만 이를 위해서는 계산할 부분의 크기( cat여기)에 따라 크기가 기하급수적으로 증가하는 복잡한 정규식이 필요합니다.

답변2

grep지정된 정규식을 기반으로 한 줄만 선택하여 인쇄합니다.

나는 출력 라인을 파이프하고 작업을 수행하기 위해 추가 명령을 사용해야 한다고 생각합니다.

일반적 으로 줄을 선택하고 문자열을 바꾸기 때문에 sedor를 사용 awk하여 없이 작업을 완료 할 수 있습니다.grep

아래에 해결책이 있습니다 awk. 다음을 사용하십시오.

awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}'

word검색하려는 문자열과 n원하는 발생 횟수를 설정해야 합니다 .

시험을 치르다:

$ awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}' file
Turbo is a cat. cat
Coco is a black cat. cat

답변3

해결 방법 은 다음과 같습니다 sed(예: 두 번째 항목을 인쇄하여 포함하고 2자신의 번호로 바꾸십시오.).

sed -n 's/cat/&\
/2
t print
d
:print
P' infile

이렇게 하면 via의 자동 인쇄가 비활성화되고 +newline의 두 번째 발생을 대체하려고 시도합니다 -n. 교체가 성공하면 개행으로 분기되어 개행으로 인쇄되고, 그렇지 않으면 해당 행이 삭제됩니다.catcat:printPd


이것을 한 줄로 작성할 gnu sed수 있습니다(예: 5번째 항목까지 인쇄).

sed -n 's/cat/&\n/5;tt;d;:t;P' infile

관련 정보