암시적 다중 패턴 일치를 원합니다.그리고모드 간에는 여러 grep을 순차적으로 실행하는 것과 같습니다.
grep pattern1 | grep pattern2 | ...
그러면 이것을 비슷한 것으로 어떻게 변환합니까?
grep pattern1 & pattern2 & pattern3
매개변수를 동적으로 구축하여 모든 것이 문자열에 맞아야 하기 때문에 단일 grep을 사용하고 싶습니다. 필터를 사용하는 것은 grep이 아닌 시스템 기능이므로 이에 대한 논거가 아닙니다.
이 질문을 다음과 혼동하지 마십시오.
grep "pattern1\|pattern2\|..."
이것은 하나입니다또는다중 패턴 일치. 나는 ~을 찾고 있다그리고패턴 매칭.
답변1
패턴 목록의 각 패턴과 일치하는 행을 찾으려면 agrep
(원래 패턴, 이제섬광, 관련성이 없는 것보다는TRE 정규식 라이브러리)은 다음 구문을 사용하여 수행할 수 있습니다.
agrep 'pattern1;pattern2'
GNU를 사용하면 grep
PCRE 지원으로 빌드할 때 다음을 수행할 수 있습니다.
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
// 종료 상태의 패턴과 일치하는 행이 있는지 여부를 반영하지 않습니다 . 다음을 수행하려면:sed
perl
awk '/pattern1/ && /pattern2/ {print; found = 1}
END {exit !found}'
perl -ne 'if (/pattern1/ && /pattern2/) {print; $found = 1}
END {exit !$found}'
또는 명령을 grep '^'
.
zgrep
잠재적으로 gzip으로 압축된 파일의 경우 일반적으로 쉘 스크립트 래퍼인 를 사용 grep
하고 위의 솔루션 중 하나를 사용하거나 (해당 구현을 사용할 수 없으므로 grep
ast-open 솔루션이 아님 ) 모듈을 사용할 수 있습니다. 입력 시 파일을 투명하게 압축 해제합니다.grep
zgrep
PerlIO::gzip
perl
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
답변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==FNR
FILENAME==ARGV[1]
ARGIND==1
gawk
이러한 함수는 매개변수로 지정된 각 문자열을 하위 문자열로 포함하는 행을 STDIN에 인쇄합니다. ga
grep 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 "$@") -; }