몇 백 개의 파일 목록에 대해 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)
grepping하는 끔찍한 해결 방법을 고려했습니다 . 셜리가 더 좋은 방법이 있습니다.
답변
파일 자체가 아닌 파일 이름 목록을 잡고있는 것 같습니다. <(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
답변
xargs grep -i -- foo /dev/null < files.txt
파일이 비어 있거나 줄 바꿈으로 구분되어 있다고 가정합니다 (따옴표 나 역 슬래시를 사용하여 구분 기호를 이스케이프 할 수 있습니다). GNU xargs
를 사용하면 구분 기호를 지정 -d
하여 인용 처리를 비활성화 할 수 있습니다 .
(unset -v IFS; set -f; grep -i -- foo $(cat files.txt))
파일이 공간, 탭 또는 줄 바꿈으로 구분되어 있다고 가정하면 (다른 구분 기호를 할당하여 다른 구분 기호를 선택할 수는 있지만 탈출 할 수는 없습니다) IFS
). 대부분의 시스템에서 파일 목록이 너무 크면 실패합니다.
또한 파일 중 어느 것도 호출되지 않는다고 가정합니다 -
.
답변
stdin에서 파일 이름 목록을 읽으려면을 사용할 수 있습니다 xargs
. 예 :
cat files.txt | xargs -d'\n' grep -i -- 'foo'
기본적 xargs
으로 공백으로 구분 된 표준 입력에서 항목을 읽습니다. 이 명령 -d'\n'
은 개행 문자를 인수 구분자로 사용하도록 지시하므로 공백이 포함 된 파일 이름을 처리 할 수 있습니다. (Stéphane Chazelas가 지적했듯이, 이것은 GNU 확장입니다). 그러나 개행을 포함하는 파일 이름에는 대처할 수 없습니다. 이를 처리하기 위해서는 약간 더 복잡한 접근법이 필요합니다.
FWIW 에서이 접근법은 while read
bash의 read
명령이 매우 느리기 때문에 루프 보다 다소 빠릅니다. 문자별로 데이터를 읽습니다.xargs
읽지 만 입력을보다 효율적으로 읽습니다. 또한 각 호출이 여러 파일 이름을 수신 할 때마다 필요한 xargs
만큼만 grep
명령을 호출 grep
하므로 각 파일 이름에 대해 개별적으로 호출하는 것보다 효율적 입니다.
자세한 내용은 xargs 매뉴얼 페이지 와 xargs 정보 페이지를 참조하십시오.
답변
xargs
files.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' {}
답변
당신은 또한 할 수 있지만 Orion의 예는 가장 간단합니다.
for i in $(cat files.txt); do grep -i 'foo' $i ; done
(files.txt에 나열된 각 파일에 대해 grep 명령을 실행하십시오.)