디렉토리 아래에있는 모든 파일을보다 간단하게 잡을 수있는 방법이 있습니까?


21

일부 내용에 대해 전체 트리를 검색하고 싶을 때

find . -type f -print0 | xargs -0 grep <search_string>

성능 또는 간결성 측면에서이를 수행하는 더 좋은 방법이 있습니까?


2
@Downvoter : 우려 사항을 공유 할 수 있다면이 질문을 기꺼이 개선하십시오.
— Dancrumb

2
많은 찾기 버전에는 xargs가 내장되어 있습니다 : find. -type f -exec fgrep <search_string> {} +
— simpleuser

답변:


42

귀하의 grep지원 -r옵션 ( 재귀 )을 확인하십시오 .

grep -r <search_string> .

1
네 ... 방금 stackoverflow.com/questions/16956810/…을 찾았 습니다. 그 대답도 있습니다.
— Dancrumb

--exclude-dir성능 문제를 해결하기 위해 의견을 추가하면 당첨자가 있습니다!
— Dancrumb

1
이것은 이식성이 없지만 grep최근 FreeBSD 및 Linux 배포판에서 지원합니다. 왜 --exclude-dir? 전체 트리 를 검색 하도록 요청하지 않았습니까 ?
— Philippos

페어 포인트 ... --exclude-dir실제로 내 유스 케이스에서 유용합니다 (하위 트리의 일부는 크지 만 쓸모가 없기 때문에). 성능에 대해 묻었지만 ... 그렇습니다. 필요하지는 않습니다.
— Dancrumb

이 경우 IIRC --exclude-dir가 GNU 전용 이라는 것을 추가해야 grep합니다. (-:
— Philippos

13

하위 최적 대답 대신의 출력 배관의 find로는 grep, 당신은 실행할 수 있습니다

find . -type f -exec grep 'research' {} '+'

그리고 voila, 두 개 대신 하나의 명령!

설명 :

find . -type f

에서 모든 일반 파일을 찾으십시오.

-exec grep 'research'

grep '연구'

{}

찾은 파일 이름에서

'+'

파일 이름 당 한 번이 아니라 모든 파일 이름 당 하나의 명령을 사용하십시오.

Nb : ';'파일 이름 당 한 번 있었을 것입니다.

그 외에도 소스 코드를 처리하는 데 사용하면 ack코드 비트를 쉽게 찾을 수 있도록을 살펴볼 수 있습니다.

ack

편집하다 :

그 연구를 조금 확장 할 수 있습니다. 먼저 -name ''스위치를 사용하여 find지정된 이름 지정 패턴을 가진 파일을 찾을 수 있습니다.

예를 들면 :

  • 로그에 해당하는 파일 만 : -name '*.log'

  • c 헤더에 해당하는 파일 만 있지만 파일 이름 확장자는 대문자 또는 소문자로 지정할 수 없습니다. -iname *.c

주의 :에 같은 grep과 ack의 -i스위치는이 경우의 경우를 구분을 의미한다.

이 경우 grep은 색상과 줄 번호없이 표시됩니다.

--color및 -n스위치 (각각 파일의 색상 및 줄 번호) 를 사용하여 변경할 수 있습니다 .

결국, 당신은 다음과 같은 것을 가질 수 있습니다 :

find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'

예를 들어

$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+' 
./test2/target.c:1:hello

5
ack대단한, 그리고 더 빠른 버전 ackIS ag(실버 수색자, geoff.greer.fm/ag )
— cfeduke

1
나는 -name '*.log'그것이 더 빠르다는 것과 같은 필터로 이것을 선호합니다 .
— sdkks

@cfeduke 내가 (당신이 가지고 무엇에 일하러!) AG의 WSL에 기본 APT 저장소의 일부가 대부분 때문에, 그것을 시도하지 않은
— 피에르 앙투안 기욤

트릭은 / dev / null을 grep에 추가하여 파일 이름을 표시하는 것입니다.
— ChuckCottrill

트릭은 디렉토리 만 검색 한 다음 -exec grep / dev / null {} / *를 사용하여 디렉토리 당 단일 포크 / exec가있는 모든 파일을 가져 오는 것입니다.
— ChuckCottrill

12

하위 디렉토리로 재귀화하려는 경우 :

grep -R 'pattern' .

이 -R옵션은 표준 옵션이 아니지만 가장 일반적인 grep구현에서 지원됩니다 .


7
GNU grep과 관련하여 심볼릭 링크를 건너 뛰는 -r대신 사용하십시오-R
— αғsнιη

1
@AFSHIN 왜 심볼릭 링크를 따르고 싶지 않습니까?
— Kusalananda

4
@Kusalananda Recursion? 현재의 GNU grep구현은 재귀를 포착 하지만 생각합니다. 그렇지 않으면 "트리"의 의미에 따라 다릅니다.
— Philippos

2
@Philippos IMHO, 사용자를 돌보는 것은 도구가 grep해야 할 일 이 아닙니다 . 만약 사용자가 디렉토리 구조에 심볼릭 링크 루프를 가지고 있다면 그것은 사용자의 문제입니다. :-)
— Kusalananda

3
@Kusalananda 그리고 시스템이 루프를 제공한다면? 절대로 길을 잃지 /sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...않았습니다 (-XI가 나를 돌보는 도구와 같이 (이상한 마법을 제공하지 않는 한 "AI"라고 부릅니다)) (-;
— Philippos

5

상술 된 바와 같이 -r또는 -R(원하는 심볼릭 처리에 의존하는) 짧은 옵션이다.

그러나 -d <action>때때로 유용 할 수 있습니다.

좋은 점은 -d건너 뛰기 명령으로, 현재 레벨을 스캔하고 싶을 때 "grep : directory_name : 디렉토리입니다"를 침묵시킵니다.

$ grep foo * 
grep: q2: Is a directory 
grep: rt: Is a directory 

$ grep -d skip foo *  
$ 

그리고 물론 :

$ grep -d recurse foo * 
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).  
$ 

이 -d skip옵션은 다른 스크립트에서 정말 편리하므로 반드시 할 필요는 없습니다 2> /dev/null. :)


0

많은 파일을 처리하는 경우 하위 폴더의 모든 파일을 가져 오는 대신 검색해야하는 파일을 정리하면 grep이 더 빨리 실행됩니다.

때때로이 형식을 사용합니다.

grep "primary" `find . | grep cpp$`

의 하위 폴더에있는 모든 파일을 찾기 .에이를 cpp. 그런 다음 해당 파일을 "1 차"로 grep하십시오.

원하는 경우 해당 결과를 계속해서 grep 호출로 파이프 할 수 있습니다.

grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"

1
backtics는 현대의 좋은 습관이 아니며 모두 쓸모가 없습니다
— Christopher

1
이름에 특수 문자가 포함 된 파일이 있으면 중단됩니다. 나는 이것이 그대로 작동하기에 너무 특별하기 위해 얼마나 특별 해야하는지 모르겠지만, 당신이하고있는 일은 실제로 ls의 출력을 파싱하는 것과 똑같습니다.
— CVn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.