파일에서 수백 개의 문자열을 위해 디렉토리에 수천 개의 파일을 grep하는 방법


11

나는 grep성명서 를 작성하려고하는데 그것이 나를 죽이고 있습니다. 또한 arguments list too long오류가 발생 하는 데 지쳤습니다 . 파일이 있는데 전화 해 봅시다 subset.txt. 여기에는와 같은 특정 문자열을 가진 수백 줄이 포함됩니다 MO43312948. 내 객체 디렉토리에는 수천 개의 파일이 있으며 문자열이 포함 된 모든 파일을 subset.txt다른 디렉토리 에 복사해야합니다 .

객체 디렉토리에서 일치하는 파일을 반환하기 위해 이것을 시작하려고했습니다.

grep -F "$(subset.txt)" /objects/*

bash : / bin / grep : Argument list too long이 계속 나타납니다.


6
"$(subset.txt)"그런 명령 을 했어요 ? 즉 , 명령 대체 이므로 쉘 이 명령 또는 스크립트처럼 실행 subset.txt 됩니다.
JigglyNaga

답변:


23

당신은을 대상으로 디렉토리를 통과 할 수 grep-R와와 입력 패턴의 파일 -f:

  -f FILE, --file=FILE
          Obtain patterns from FILE, one per line.  If this option is used
          multiple  times  or  is  combined with the -e (--regexp) option,
          search for all patterns given.  The  empty  file  contains  zero
          patterns, and therefore matches nothing.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

그래서 당신은 찾고 있습니다 :

grep -Ff subset.txt -r objects/

다음을 사용하여 일치하는 파일 목록을 얻을 수 있습니다.

grep -Flf subset.txt -r objects/

따라서 최종 목록이 너무 길지 않은 경우 다음을 수행 할 수 있습니다.

 mv $(grep -Flf subset.txt -r objects/) new_dir/

그는 반환하면 argument list too long오류, 사용 :

grep -Flf subset.txt -r objects/ | xargs -I{} mv {} bar/

파일 이름에 공백이나 다른 이상한 문자가 포함될 수 있으면 (GNU 가정 grep)을 사용하십시오.

grep -FZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

마지막으로 이진 파일을 제외하려면 다음을 사용하십시오.

grep -IFZlf subset.txt -r objects/ | xargs -0I{} mv {} bar/

… 또는 mv각각 하나의 인수로 잠재적으로 수천 번의 호출 을 피하기 위해 ... | xargs -0 mv -t bar/( 옵션을 mv지원 한다고 가정 -t).
David Foerster

11

사용하다

grep -F -f subset.txt 

grep에게 subset.txt파일 에서 읽도록 지시 합니다.

당신은 파일을 걸어 찾기를 사용할 수 있습니다.

find . -type f -exec grep -F -f subset.txt {} \;

또는

find . -type f -exec grep -F -f subset.txt {}  +

추가 필터링을 수행하는 것 이외 find-r다른 장점이 있습니까?
phk

1
@phk grep -r는 일반 파일에 대한 심볼릭 링크를 검색하며 바람직하지 않을 수도 있습니다 (동일한 트리 내부를 가리키는 경우 동일한 파일을 두 번 검색합니다. 원하는).
Gilles 'SO- 악의를 멈춰라'

최신 버전에는 grep기호 링크와의 상호 작용을 제어하는 ​​옵션이 있습니다 ( man grep현재 시스템의 세부 사항을 결정하기 위해). 재귀는 grep될 것 많은 실행보다 빠르게 grep통해 모든 파일에 개별적으로 find.
페리

1
@ 페리 확실합니까? 왜? 또한이 답변은을 사용 -exec +하므로 파일을 그룹화하고 파일 당 하나의 grep을 실행하지 않습니다.
terdon

나는 정정했다. 나는 다른 의미를 알지 못했다. -exec {} +-exec {} \;... 매일 새로운 것을 배운다 ( 프로세스 생성 및 패턴 파싱 오버 헤드로 인해 단일 재귀 grep가 여러 번 grep실행되는 것보다 빠르지 않을 이유가 없다. find직접 백업 할 특정 번호가 없습니다).
Perry

3

grep 속도를 더 높이려면 쉘을 실행하기 전에 로케일을 설정할 수 있습니다 (예 : "LC_ALL = c"사용). 이것은 grep에 상속되며 필요하지 않을 때 유니 코드 처리를 비활성화하며 경우에 따라 grep 속도를 크게 높일 수 있습니다. 이를 설명하는 훌륭한 블로그는 http://www.inmotionhosting.com/support/website/ssh/speed-up-grep-searches-with-lc-all 에서 찾을 수 있습니다 . 이 트릭은 grep뿐만 아니라 bash 쉘 스크립트의 속도를 높일 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.