암시 적 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>
모두 정확히 , 는 a
및 b
모두 있을 수있는 문자열이 없기 때문에 일치하지 않습니다. 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==FNR
를 FILENAME==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 "$@") -; } gai(){ awk "FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1" <(printf %s\\n "$@") -; }
댓글
- 여러 사용 사례 및 작업을 다루는 선명한 답변 (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 "$@" } 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”>
)는 질문에서 바로 주어진 훨씬 더 쉬운 솔루션입니다.
AND
연산자에 대해 묻고 있었는데, 이는 파일이 패턴 A와 패턴과 일치하는 경우에만 긍정적 인 히트임을 의미합니다. B와 패턴 C 그리고 … AND
만약 당신의 경우 파일이 다음과 같으면 긍정적 인 것입니다. 패턴 A 또는 패턴 B 또는 … 이제 차이점이 보이십니까? AND
를 계산해야합니다. 그런 다음 여러 파일에서 실행되도록 스크립트를 다시 작성해야합니다. 그러면 질문에 이미 답변이 있고 시도가 테이블에 아무 것도 가져 오지 않는다는 것을 깨달을 수 있습니다. 죄송합니다.
foo
를 포함하는 줄과bar
를 포함하는 줄을 찾기위한 grep 구문 ” 여러 검색 패턴에 grep 사용