목록의 grep 파일

목록의 grep 파일

수백 개의 파일 목록에 대해 grep을 실행하려고 합니다.

$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php

그러나 파일에서 발견된 것으로 알고 있는 문자열을 찾고 있더라도 다음은 파일을 검색하지 않습니다.

$ grep -i 'foo' <(cat files.txt)

$ grep -i 'foo' admin.php
The foo was found

나는 깃발에 대해 잘 알고 -f있으며 다음과 같이 읽을 것입니다.무늬파일에서. 하지만 어떻게 읽어야 할까?입력 파일?

cp나는 해당 형식을 지원하는 것으로 보이는 <(cat files.txt)임시 디렉터리에 파일을 복사한 다음 거기에서 파일을 가져오는 끔찍한 해결 방법을 고려했습니다 .Shirley에게는 더 좋은 방법이 있습니다.

답변1

파일 자체가 아닌 파일 이름 목록을 찾고 있는 것 같습니다. <(cat files.txt)파일을 나열하면 됩니다. <(cat $(cat files.txt))실제로 연결하여 단일 스트림으로 검색해 보세요 . 또는

grep -i 'foo' $(cat files.txt)

모든 파일에 대해 grep을 제공하십시오.

그러나 목록에 파일이 너무 많으면 매개변수 수에 문제가 발생할 수 있습니다. 그럴땐 그냥 씁니다

while read filename; do grep -Hi 'foo' "$filename"; done < files.txt

답변2

xargs grep -i -- foo /dev/null < files.txt

파일이 공백 또는 개행으로 구분되어 있다고 가정합니다(따옴표나 백슬래시를 사용하여 이러한 구분 기호를 이스케이프할 수 있음). GNU를 사용하면 xargs구분 기호를 지정할 수 있습니다 -d(그러나 인용 처리는 비활성화됩니다).

(unset -v IFS; set -f; grep -i -- foo $(cat files.txt))

파일은 공백, 탭 또는 줄 바꿈으로 구분되는 것으로 가정됩니다. 에 할당하여 다른 구분 기호를 선택할 수는 있지만 이러한 구분 기호를 벗어날 수 있는 방법은 없습니다 IFS. 대부분의 시스템에서 파일 목록이 너무 크면 작업이 실패합니다.

또한 -.

답변3

표준 입력에서 파일 이름 목록을 읽으려면 다음을 사용할 수 있습니다 xargs.

cat files.txt | xargs -d'\n' grep -i -- 'foo'

기본적으로 xargs항목은 공백으로 구분된 표준 입력에서 읽습니다. -d'\n'공백이 포함된 파일 이름을 처리할 수 있도록 개행 문자를 매개변수 구분 기호로 사용하도록 지시합니다 . (Stéphane Chazelas가 지적했듯이 이것은 GNU 확장입니다.) 그러나 개행 문자가 포함된 파일 이름은 처리할 수 없습니다. 이를 처리하려면 좀 더 복잡한 방법이 필요합니다.

FWIW, 이 방법은 while readbash의 명령이 매우 느리기 때문에 루프보다 약간 빠릅니다 read. 데이터를 문자별로 읽는 반면 xargs입력을 읽는 것이 훨씬 더 효율적입니다. 또한 필요한 만큼 명령을 호출하면 됩니다. xargs각 호출은 여러 파일 이름을 수신하므로 각 파일 이름에 대해 개별적으로 호출하는 것보다 더 효율적입니다.grepgrep

보다xargs 매뉴얼 페이지자세한 내용은 xargs 정보 페이지를 참조하세요.

답변4

xargsfiles.txt해당 옵션을 사용하여 파일에서 항목(예: 목록)을 읽을 수 있습니다 .

   --arg-file=file
   -a file
          Read items from file instead of standard input.  If you use this
          option, stdin remains unchanged when commands are  run.   Other‐
          wise, stdin is redirected from /dev/null.

따라서 이 방법도 작동합니다.

xargs -a files.txt grep -i 'foo'

또는 파일 이름에 공백이 있음

xargs -d'\n' -a files.txt grep -i 'foo'
xargs -I{} -a files.txt grep -i 'foo' {}

관련 정보