암시 적 AND 패턴 사이, 즉 시퀀스에서 여러 greps를 실행하는 것과 동일합니다.

grep pattern1 | grep pattern2 | ... 

어떻게이를 다음과 같이 변환 할 수 있습니까?

grep pattern1 & pattern2 & pattern3 

인수를 동적으로 구축하고 있으므로 모든 것이 하나의 문자열에 맞아야하므로 단일 grep을 사용하고 싶습니다. 필터를 사용하는 것은 grep이 아닌 시스템 기능이므로 이에 대한 논쟁이 아닙니다.


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

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

또는 다중 패턴 일치입니다.

댓글

답변

agrep는 다음 구문으로 수행 할 수 있습니다.

agrep "pattern1;pattern2" 

GNU grep를 사용하여 빌드시 ith PCRE 지원으로 다음을 수행 할 수 있습니다.

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

ast grep :

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

(.*를 는 <x><y> 모두 정확히 , 는 ab 모두 있을 수있는 문자열이 없기 때문에 일치하지 않습니다. div> 동시에).

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

grep -e "pattern1.*pattern2" -e "pattern2.*pattern1" 

가장 좋은 이식 방법은 이미 언급했듯이 awk를 사용하는 것입니다.

awk "/pattern1/ && /pattern2/" 

sed :

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

모두 정규식 구문이 다르므로주의하세요.

댓글

  • agrep 구문이 작동하지 않습니다. 나 … 어떤 버전이 도입 되었나요?
  • @Raman 1992 년의 2.04 는 이미 사용했습니다. 저는 ‘ 처음부터 ‘가 아니라고 믿을 이유가 없습니다. agrep의 최신 버전 (1992 년 이후)은 glimpse / webglimpse 에 포함되어 있습니다. 아마도 당신은 다른 구현을 가지고있을 것입니다. 하지만 ast-grep 버전에는 실수가 있었지만 증강 정규 표현식 의 옵션은 -A div가 아니라 -X입니다. >.
  • @St é phaneChazelas 감사합니다. Fedora 23에 agrep 0.8.0이 있습니다. 참조하는 것과 다른 agrep이어야합니다.
  • @Raman, 당신의 소리는 TRE agrep .
  • @Techiee 또는 awk '/p1/ && /p2/ {n++}; END {print 0+n}'

답변

당신은 grep 버전을 지정하지 않았습니다. 이것은 중요합니다. 일부 정규 표현식 엔진은 “& “하지만 이것은 비표준 및 이식 불가능한 기능입니다. 그러나 적어도 GNU grep은 이것을 지원하지 않습니다.

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

 awk "/regexp1/ && /regexp2/ && /regexp3/ { print; }" 

처럼 보이고 명령 줄에 쉽게 지정되도록 구성 할 수 있습니다.

Comments

  • awk는 ERE ‘를 사용합니다. 일반 grep에서 사용하는 BRE ‘와 달리 grep -E에 해당합니다.
  • awk ‘의 정규식은 ERE로 호칭 하지만 실제로는 ‘ 약간 특이합니다. 다음은 누구보다 자세한 내용입니다. wiki.alpinelinux.org/wiki/Regex
  • 감사합니다. grep 2.7.3 ( openSUSE). 찬성했지만 잠시 동안 질문을 열어 두겠습니다. grep에 대한 트릭이있을 수 있습니다 (awk를 싫어하는 것이 아니라 단순히 더 많은 것을 아는 것이 좋습니다).
  • 기본 작업은 일치하는 줄을 인쇄하여 { print; } 부분이 ‘ 여기서 실제로 필요하거나 유용하지 않도록하는 것입니다.

Answer

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 -  

입력 한 줄이없는 대신 모두 인쇄하려면 patterns가 비어있는 경우 NR==FNRFILENAME==ARGV[1] 또는 ARGIND==1 in 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 "[email protected]") -; } gai(){ awk "FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1" <(printf %s\\n "[email protected]") -; }  

댓글

  • 여러 사용 사례 및 작업을 다루는 선명한 답변 (macos에서 확인)

답변

grep pattern1 | grep pattern2 | ...

인수를 동적으로 빌드하므로 단일 grep을 사용하고 싶습니다. 따라서 모든 것이 하나의 문자열에 맞아야합니다.

실제로 파이프 라인을 동적으로 빌드 할 수 있습니다 (eval에 의존하지 않고) :

 # Executes: grep "$1" | grep "$2" | grep "$3" | ... function chained-grep { local pattern="$1" if [[ -z "$pattern" ]]; then cat return fi shift grep -- "$pattern" | chained-grep "[email protected]" } cat something | chained-grep all patterns must match order but matter dont  

아마도 매우 효율적인 솔루션은 아닙니다.

댓글

  • chained-grep() 또는 function chained-grep를 사용하고 function chained-grep()는 사용하지 마십시오. unix.stackexchange.com/questions/73750/…
  • 이 트릭이 무엇인지 설명해 주시겠습니까? 답변에 추가 할 수 있습니까 ( 없음 ” 편집 : “, ” 업데이트 : ” 또는 이와 유사한) 수정 하시겠습니까?
  • 트릭을 더 명확하게 만들기 위해 답변을 수정했습니다 (예 : 쉘 파이프 라인을 동적으로 구축)

Answer

git grep

다음은 git grep 부울 표현식을 사용하여 여러 패턴 결합 :

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

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

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

man git-grep를 참조하세요.

참조 :

OR 작업의 경우 다음을 참조하십시오.

댓글

  • 훌륭한 답변입니다. 감사합니다.

답변

여기에 내 의견이 있으며 여러 줄의 단어에 적용됩니다.

find . -type f 뒤에
-exec grep -q "first_word" {} \;
및 마지막 키워드
-exec grep -l "nth_word" {} \;

-q 조용 / 무음
-l 파일 표시 일치 포함

다음은 “rabbit”및 “hole”이라는 단어가 포함 된 파일 이름 목록을 반환합니다.
find . -type f -exec grep -q "rabbit" {} \; -exec grep -l "hole" {} \;

댓글

  • 주의 깊게 살펴보면 이것이 질문에서 요구하는 기능이 아님을 알 수 있습니다.

답변

ripgrep

다음은 rg 를 사용한 예입니다.

rg -N "(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)" file.txt 

Rust “의 정규식 엔진 은 유한 자동 장치, SIMD 및 공격적인 리터럴 최적화를 사용하여 매우 빠르게 검색합니다.

GH-875 .

답변

모든 단어 (또는 패턴)를 찾으려면 for 루프에서 grep를 실행할 수 있습니다. 여기서 가장 큰 장점은 정규 표현식 목록 에서 검색하는 것입니다.

실제 예 :

# File "search_all_regex_and_error_if_missing.sh" find_list="\ ^a+$ \ ^b+$ \ ^h+$ \ ^d+$ \ " for item in $find_list; do if grep -E "$item" file_to_search_within.txt then echo "$item found in file." else echo "Error: $item not found in file. Exiting!" exit 1 fi done 

이제이 파일에서 실행 해 보겠습니다.

hhhhhhhhhh aaaaaaa bbbbbbbbb ababbabaabbaaa ccccccc dsfsdf bbbb cccdd aa caa 
$ ./search_all_regex_and_error_if_missing.sh aaaaaaa aa ^a+$ found in file. bbbbbbbbb bbbb ^b+$ found in file. hhhhhhhhhh ^h+$ found in file. Error: ^d+$ not found in file. Exiting! 

댓글

  • 논리가 잘못되었습니다. ALL 연산자를 사용하면 코드가 AND가 아닌 OR 연산자로 작동합니다. 그리고 btw. id = “41bec908a4”>

)는 질문에서 바로 주어진 훨씬 더 쉬운 솔루션입니다.

  • @greenoldman 논리는 간단합니다. for will 모든 단어 / 패턴에 대해 반복 목록에 있고 파일에있는 경우 인쇄됩니다. 따라서 단어를 찾을 수없는 경우 조치가 필요하지 않으면 ‘ else를 제거하십시오.
  • 당신의 논리와 제 질문을 이해합니다. AND 연산자에 대해 묻고 있었는데, 이는 파일이 패턴 A와 패턴과 일치하는 경우에만 긍정적 인 히트임을 의미합니다. B와 패턴 C 그리고 … AND 만약 당신의 경우 파일이 다음과 같으면 긍정적 인 것입니다. 패턴 A 또는 패턴 B 또는 … 이제 차이점이 보이십니까?
  • @greenoldman이 루프가 모든 패턴에 대해 AND 조건을 검사하지 않는 이유를 모르십니까? 그래서 저는 ‘ 실제 예제로 제 답변을 편집했습니다. 파일에서 모든 정규식 목록을 검색하고 누락 된 첫 번째 항목에서 오류로 종료됩니다. li>
  • 당신은 바로 눈앞에 있고, 당신은 첫 경기가 실행 된 직후에 긍정적 인 경기를합니다. 모든 결과를 ” 수집 “하고 AND를 계산해야합니다. 그런 다음 여러 파일에서 실행되도록 스크립트를 다시 작성해야합니다. 그러면 질문에 이미 답변이 있고 시도가 테이블에 아무 것도 가져 오지 않는다는 것을 깨달을 수 있습니다. 죄송합니다.
  • 답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다