grep을 사용하여 중첩된 디렉터리 구조에서 다음을 포함하는 파일을 검색하는 방법모두내 검색 패턴에 포함된 단어는 무엇입니까?
여러 단어가 포함된 파일을 찾기 위해 grep을 사용하고 싶습니다. foo bar와 bah를 사용해 보겠습니다. 할 수 있지만 grep -rl foo |xargs grep -rl bah| ...etc
더 쉬운 방법이 있나요? 검색할 문자열 파일로 -F를 사용할 수 있다는 것을 알고 있지만 여전히 OR 연산자(합집합)를 사용하여 문자열을 검색하고 AND 연산자(교차)를 사용해야 한다고 생각합니다.
답변1
find
+awk
해결책:
find . -type f -exec awk '/\<foo\>/{ p1=1 }/\<bar\>/{ p2=1 }/\<bah\>/{ p3=1 }
p1 && p2 && p3{ print FILENAME; exit }' {} +
awk
프로그램 세부정보:
/\<foo\>/{ p1=1 }/\<bar\>/{ p2=1 }/\<bah\>/{ p3=1 }
- 각각의 필수 패턴이 발견되면 해당 플래그를 설정합니다.p1 && p2 && p3
- 모든 패턴이 발견되면:print FILENAME
- 현재 인쇄파일 이름/파일 경로exit
- 스크립트 실행 즉시 종료
답변2
내 대답은 @RomanPerekhrest의 답변과 유사합니다. 주요 차이점은 레코드 구분 기호( )를 입력의 어떤 항목과도 일치하지 않는 항목(예:)으로 설정하여 awk
전체 입력을 한 번에 처리 할 수 있다는 사실을 활용한다는 것입니다. 즉, 전체 파일을 삼켜 마치 하나의 문자열인 것처럼 검색합니다.RS
^$
예를 들어
find . -type f -exec \
awk -v RS='^$' '/foo/ && /bar/ && /baz/ { print FILENAME }' {} +
.
현재 디렉터리( )에 포함된 모든 파일이 나열됩니다 .모두정규식 foo
, bar
및 baz
. 정규식 중 일부 또는 전부를 전체 단어로 처리해야 하는 경우 단어 경계 앵커로 묶습니다 \<
( \>
예: ) \<foo\>
.
또한 각 파일을 한 번 포크하지 않기 때문에 더 빠르게 실행됩니다 awk
. 대신 awk
명령줄 버퍼에 맞는 만큼 많은 파일 이름 인수를 사용하여 실행됩니다(최신 시스템에서는 일반적으로 128K 또는 1 또는 2M 문자).... 예를 들어, find
1000개의 파일이 발견 되면 awk
한 번만 실행되고 1000번은 실행되지 않습니다. .
노트:이를 위해서는 정규 표현식이 awk
허용되는 버전이 필요합니다. RS
바라보다awk의 후루룩 모드?다른 버전의 awk에서 제한된 형태의 "slurp 모드"를 구현하는 방법에 대한 자세한 내용과 예를 보려면 계속 읽어보세요.
또한 참고하십시오:그러면 메모리에 있는 각 파일의 전체 내용을 한 번에 하나씩 읽습니다. 수십 기가바이트 이상의 로그 파일과 같은 매우 큰 파일의 경우 사용 가능한 RAM 또는 RAM+SWAP을 초과할 수 있습니다. 이런 일이 일어날 가능성은 거의 없지만 만약 발생한다면 심각한 문제가 발생할 수 있습니다(예를 들어 Linux에서 RAM과 SWAP가 부족하면 커널이 무작위 프로세스를 종료하기 시작합니다).
답변3
이와 같은 논리적 AND의 경우 일반적으로 다음을 사용합니다 awk
.
awk '/foo/ && /bar/ && /bah/ { print }' /path/to/file
답변4
grep
다음과 함께 GNU를 사용하세요-P
(펄 호환성)옵션과긍정적인 예측 정규식(?=(regex))
한 줄이나 전체 파일에서 순서에 관계없이 단어를 찾고, 현재 디렉터리에서 시작하는 모든 파일에서 반복적으로 단어를 찾습니다.
grep -rlP '(?s)(?=.*?\bfoo\b)(?=.*?\bbar\b)(?=.*?\bbah\b)' .
(?s)
이것은 DOTALL 수정자이며 다음을 허용합니다.가리키다\newlines를 일치시키기 위해(.|\n)*?
Too 및 betweenwords를 사용합니다[\s\S]*?
.at
\bWORD\b
;\b
은 단어 경계 앵커 포인트입니다.
다음을 입력:
==> file1 <== foo here and bar bah and of file1 ==> file2 <== foo then bar and bah ==> file3 <== foo foobarbah ba ==> file4 <== this is foo bar bahh bah
출력은 다음과 같습니다
./file1
./file2
./sub-dir/file4