수천 개의 파일에 대한 Grep

수천 개의 파일에 대한 Grep

내 디렉토리에 cca 26,000개의 파일이 있고 모든 파일을 grep해야 합니다. 문제는 가능한 한 빨리 가져와야 하므로 find 명령에서 파일 이름을 가져와 일치 항목을 파일에 쓰는 grep 스크립트를 만드는 것이 이상적이지 않다는 것입니다. "매개변수 목록이 너무 김" 문제가 발생하기 전에 이러한 모든 파일을 수집하는 데 약 2분이 걸렸습니다. 어떻게 해야할지 아이디어가 있나요? 편집: 새 파일을 계속 생성하는 스크립트가 있으므로 모든 파일을 다른 디렉터리에 넣는 것은 불가능합니다.

답변1

그리고 find:

cd /the/dir
find . -type f -exec grep pattern {} +

( -type f검색 전용입니다.정기적인파일(일반 파일을 가리킨다 하더라도 심볼릭 링크도 아님). 디렉터리를 제외한 모든 유형의 파일을 검색하려는 경우(그러나 fifos 또는 /dev/zero와 같은 일부 파일 유형은 일반적으로 읽고 싶지 않음) -type fGNU 특정 파일로 바꾸십시오 ! -xtype d( -xtype d다음 파일과 일치). 유형목차심볼릭 링크 해결 후)).

GNU 사용 grep:

grep -r pattern /the/dir

(그러나 최신 버전의 GNU grep이 없으면 디렉토리에 들어갈 때 심볼릭 링크를 따라야 합니다.) 옵션을 추가하지 않으면 특이한 파일은 검색되지 않습니다 -D read. 그러나 최신 버전의 GNU는 grep여전히 심볼릭 링크 내에서 검색하지 않습니다.

아주 오래된 버전의 GNU는 find표준 구문을 지원하지 않지만 {} +비표준 구문을 사용할 수 있습니다.

cd /the/dir &&
  find . -type f -print0 | xargs -r0 grep pattern

성능에 따라 I/O가 제한될 수 있습니다. 즉, 검색을 수행하는 데 걸리는 시간은 저장소의 모든 데이터를 읽는 데 걸리는 시간입니다.

데이터가 중복 디스크 배열에 있는 경우 여러 파일을 동시에 읽으면 성능이 향상될 수 있습니다(그렇지 않으면 성능이 저하될 수 있음). 동시성은 성능이 I/O 바인딩되지 않고(예를 들어 모든 데이터가 캐시에 있기 때문에) CPU가 여러 개인 경우에도 greps도움이 될 수 있습니다 . GNU xargs의 옵션을 사용하여 -P이를 수행 할 수 있습니다 .

예를 들어, 데이터가 3개의 드라이브가 있는 RAID1 배열에 있거나 데이터가 캐시에 있고 3개의 CPU가 유휴 상태인 경우:

cd /the/dir &&
  find . -type f -print0 | xargs -n1000 -r0P3 grep pattern

(여기서는 1000개 파일마다 -n1000새 파일을 생성하고 grep한 번에 최대 3개 파일을 병렬로 실행하는 데 사용되었습니다.)

그러나 의 출력 grep이 리디렉션되면 3개의 프로세스에서 심각하게 인터리브된 출력이 생성됩니다 grep. 이 경우 다음과 같이 실행할 수 있습니다.

find . -type f -print0 | stdbuf -oL xargs -n1000 -r0P3 grep pattern

(최근 GNU 또는 FreeBSD 시스템에서) 또는 --line-bufferedGNU 옵션을 사용하십시오 grep.

pattern고정 문자열인 경우 이 옵션 을 추가하면 -F문제가 개선될 수 있습니다.

멀티바이트 문자 데이터가 아니거나 패턴 일치를 위해 데이터가 멀티바이트 문자인지 여부가 중요하지 않은 경우 다음을 수행합니다.

cd /the/dir &&
  LC_ALL=C grep -r pattern .

성능을 크게 향상시킬 수 있습니다.

이러한 유형의 검색을 자주 수행하게 되면 많은 검색 엔진 중 하나를 사용하여 데이터를 색인화할 수 있습니다.

답변2

대부분의 파일 시스템의 경우 단일 디렉터리에 26,000개의 파일이 있으면 많은 양입니다. 이 큰 목차를 읽는 데는 상당한 시간이 걸릴 수 있습니다. 각각 수백 개의 파일만 포함하는 더 작은 디렉터리로 분할하는 것을 고려하세요.

find잘못한 것이 아니라면 전화를 해도 성능 저하가 설명되지 않습니다. 이는 디렉토리를 탐색하는 빠른 방법이며 너무 긴 명령줄을 실행하려고 시도할 위험이 없도록 보장합니다. 파일당 한 번 수행 하는 -exec grep PATTERN {} +대신 각 명령 호출에서 가능한 한 많은 파일을 압축하는 를 사용하십시오 . 파일당 한 번 명령을 실행하면 눈에 띄게 느려질 수 있습니다.-exec grep PATTERN {} \;grep

답변3

모든 파일을 여러 번 grep해야 하는 경우(말씀하신 대로 스크립트 실행) 램 디스크를 살펴보고 모든 파일을 거기에 복사한 다음 파일을 여러 번 grep하면 검색 속도가 빨라질 것입니다. 최소 100번.

충분한 메모리만 있으면 됩니다. 그렇지 않으면 파일 색인화를 고려해야 합니다. lucene 또는 nosql 데이터베이스로 이동하여 이에 대해 쿼리를 실행합니다.

답변4

디렉토리의 모든 파일

grep 'search string' *

재귀적으로

grep -R 'search string' *

관련 정보