여러 AND 패턴으로 grep을 실행하는 방법은 무엇입니까?

여러 AND 패턴으로 grep을 실행하는 방법은 무엇입니까?

암시적 다중 패턴 일치를 원합니다.그리고모드 간에는 여러 grep을 순차적으로 실행하는 것과 같습니다.

grep pattern1 | grep pattern2 | ...

그러면 이것을 비슷한 것으로 어떻게 변환합니까?

grep pattern1 & pattern2 & pattern3

매개변수를 동적으로 구축하여 모든 것이 문자열에 맞아야 하기 때문에 단일 grep을 사용하고 싶습니다. 필터를 사용하는 것은 grep이 아닌 시스템 기능이므로 이에 대한 논거가 아닙니다.


이 질문을 다음과 혼동하지 마십시오.

grep "pattern1\|pattern2\|..."

이것은 하나입니다또는다중 패턴 일치. 나는 ~을 찾고 있다그리고패턴 매칭.

답변1

패턴 목록의 각 패턴과 일치하는 행을 찾으려면 agrep(원래 패턴, 이제섬광, 관련성이 없는 것보다는TRE 정규식 라이브러리)은 다음 구문을 사용하여 수행할 수 있습니다.

agrep 'pattern1;pattern2'

GNU를 사용하면 grepPCRE 지원으로 빌드할 때 다음을 수행할 수 있습니다.

grep -P '^(?=.*pattern1)(?=.*pattern2)'

그리고ASTgrep:

grep -X '.*pattern1.*&.*pattern2.*'

( s를 일치 문자열 .*로 추가하여 및<x>&<y><x><y> 정확히, a&b그러한 문자열은 일치하지 않으므로 절대 일치하지 않습니다.동시에 a) b.

패턴이 겹치지 않으면 다음을 수행할 수도 있습니다.

grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'

가장 좋은 휴대용 방법은 아마도 awk위와 같을 것입니다.

awk '/pattern1/ && /pattern2/'

또는 다음을 사용하여 sed:

sed -e '/pattern1/!d' -e '/pattern2/!d'

또는 perl:

perl -ne 'print if /pattern1/ && /pattern2/'

이들 모두에는 서로 다른 정규식 구문이 있습니다.

awk// 종료 상태의 패턴과 일치하는 행이 있는지 여부를 반영하지 않습니다 . 다음을 수행하려면:sedperl

awk '/pattern1/ && /pattern2/ {print; found = 1}
     END {exit !found}'
perl -ne 'if (/pattern1/ && /pattern2/) {print; $found = 1}
          END {exit !$found}'

또는 명령을 grep '^'.

zgrep잠재적으로 gzip으로 압축된 파일의 경우 일반적으로 쉘 스크립트 래퍼인 를 사용 grep하고 위의 솔루션 중 하나를 사용하거나 (해당 구현을 사용할 수 없으므로 grepast-open 솔루션이 아님 ) 모듈을 사용할 수 있습니다. 입력 시 파일을 투명하게 압축 해제합니다.grepzgrepPerlIO::gzipperl

perl -MPerlIO::gzip -Mopen='IN,gzip(autopop)' -ne '
  print "$ARGV:$_" if /pattern1/ && /pattern2/' -- *.gz

zgrep(파일이 충분히 작은 경우 각 파일에 대해 실행하지 않고 내부적으로 압축 해제를 수행하는 것보다 적어도 더 효율적입니다 gunzip.)

답변2

중요한 grep 버전을 지정하지 않았습니다. 일부 정규식 엔진은 "&"를 사용하여 AND를 통해 여러 일치 항목을 허용하지만 이는 비표준이며 이식할 수 없는 기능입니다. 그러나 적어도 GNU grep은 이를 지원하지 않습니다.

OTOH, grep을 sed, awk, perl 등으로 간단히 대체할 수 있습니다(가중치가 증가하는 순서대로 나열됨). awk를 사용하면 명령은 다음과 같습니다.

awk '/regexp1/ && /regexp2/ && /regexp3/ { 인쇄 }'

그리고 간단한 방법으로 명령줄에서 지정하도록 구성할 수 있습니다.

답변3

git grep

사용된 구문은 다음과 같습니다.git grep여러 패턴을 결합하여 사용부울 값표현:

git grep --no-index -e pattern1 --and -e pattern2 --and -e pattern3

위 명령은 모든 패턴과 일치하는 행을 한 번에 인쇄합니다.

--no-indexGit에서 관리하지 않는 파일을 현재 디렉터리에서 검색합니다.

도움을 확인하세요 man git-grep.

또한보십시오:

~을 위한또는작업을 참조하세요.

답변4

patterns각 줄에 패턴이 포함되어 있으면 다음을 수행할 수 있습니다.

awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -

또는 정규식 대신 하위 문자열과 일치합니다.

awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -

none 을 인쇄하는 대신 비어 있는 경우 모든 입력 줄을 인쇄하려면 , 또는 in 으로 patterns바꾸십시오 .NR==FNRFILENAME==ARGV[1]ARGIND==1gawk

이러한 함수는 매개변수로 지정된 각 문자열을 하위 문자열로 포함하는 행을 STDIN에 인쇄합니다. gagrep all을 나타내고 gai대소문자를 무시합니다.

ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\\n "$@") -; }

관련 정보