고정된 수의 패턴 발생이 포함된 행 필터링

고정된 수의 패턴 발생이 포함된 행 필터링

파일이 있다고 가정

foo bar cat dog
foo foo cat bar
bar foo foo foo

foo예를 들어 숫자가 다음과 같은 경우 특정 횟수만큼 발생하는 행을 찾기 위해 어떻게 grep할 수 있습니까?1예제 파일의 첫 번째 줄만 인쇄해야 합니까?

답변1

$ grep 'foo' file | grep -v 'foo.*foo'

먼저 가 있는 모든 행을 선택한 foo다음 가 있는 모든 행을 삭제하고 해당 행 내의 다른 행을 foo삭제합니다 .foo

모든 행에 하나 이상의 행이 포함되어 있으면 foo(예에서와 같이) 첫 번째 행을 건너뛸 수 있습니다 grep.

grep정확하게 어떻게 해야 합니까?질소문자열이 나타납니까? ”: grep적어도 다음을 포함하는 줄의 경우질소일치시킨 후 행 삭제N+1(또는 그 이상) 일치합니다.

답변2

일반적인 경우 - 정확한 행만 인쇄질소awk'를 사용하여 gsub()번호를 반환 할 수 있습니다 . 대체를 수행하고 존재하지 않는 경우 행을 인쇄하십시오. 요구 사항을 충족합니다. 예를 들어 정확히 3번 나타나는 줄을 인쇄합니다.

 awk '{l=$0;t=gsub(/foo/,"",l)}t==3' infile

또 다른 방법 sed:

sed 's/foo/&/3   
t x
: k
d
: x
s/foo/&/4
t k' infile

이는 세 번째 항목을 자체적으로 바꾸려고 시도하고 실패하면 줄을 삭제합니다 d. 성공하면 : x네 번째 항목을 자체적으로 바꾸려고 시도합니다. 성공하면(3개 이상이 나타남을 의미) : k(라인도 삭제되도록) 로 분기하고 , 그렇지 않으면 아무 작업도 수행하지 않습니다(라인을 자동으로 인쇄하는 것 제외). ..)


예제의 특정 사례(한 번만 나타나는 행)의 경우 다음을 사용할 수도 있습니다.

sed '/foo/!d;/foo.*foo/d' infile

또는 이와 유사한 것:

pcregrep '^(?:(?!foo).)*foo((?:(?!foo).)*)$' infile

답변3

grep -c계산에 사용 :

while read line; do [[ $(echo $line | sed 's/ /\n/g' | grep -c foo) == 2 ]] && echo "$line"; done < file.txt

답변4

또 다른 옵션은 를 사용하는 것입니다 perl. 예를 들어 일치 항목을 목록 컨텍스트에 푸시한 다음 스칼라 컨텍스트에서 테스트합니다.

perl -ne 'my $count = () = $_ =~ /foo/g; print if $count == 1' file

또는 명시적인 스칼라 변수가 없습니다.

perl -ne 'print if ( () = $_ =~ /foo/g ) == 1' file

이 접근 방식은 원하는 다른 수의 일치 항목이 있는 행을 반환하도록 쉽게 일반화됩니다.

예시 보기문자열에서 일치하는 항목의 수를 계산하기 위한 Perl의 지름길이 있습니까?

관련 정보