find 명령으로 리턴 된 파일 목록을 cat로 파이프하여 모든 파일을 보는 방법


204

나는 일을하고 find파일 목록을 얻고 있습니다. cat(cat가 모든 파일의 내용을 표시하도록) 과 같은 다른 유틸리티로 파이프 하고 기본적으로 grep이러한 파일에서 무언가를 필요로 하는 방법은 무엇입니까 ?

답변:


340
  1. 다른 프로세스로 파이핑 (이 작업을 수행하려고했지만 달성하지는 못함) :

    command1 | command2
    

    이것은 command1의 출력을 command2의 입력으로 보냅니다.

  2. -execfind(이것은 당신이하고 싶은 일을 할 것입니다-그러나 특정합니다 find)

    find . -name '*.foo' -exec cat {} \;
    

    ( 이미 사용하고있는 find 술어 사이 find와. 사이에있는 모든 것은 명령에서 찾은 특정 파일 ( 이 경우) 을 대체합니다 -exec. {}명령 을 종료하는 것 입니다.)cat {}\;-exec

  3. 한 프로세스의 출력을 다른 프로세스에 명령 행 인수로 전송

    command2 `command1`
    

    예를 들면 다음과 같습니다.

    cat `find . -name '*.foo' -print`
    

    (이것은 정규 인용 부호가 아닌 BACK-QUOTES입니다 (내 키보드의 물결표 ~ 아래에 있음). 이것은 명령 줄 인수 command1로 출력을 보냅니다 command2. 그러나 공백 (줄 바꾸기 등)이 포함 된 파일 이름은 별도의 인수로 구분됩니다.


2
고양이 find -name '*.foo' -print는 나를 위해 위대한 일을 ... 감사합니다
Devang Kamdar

역 따옴표는 훌륭하게 작동하며보다 일반화되어 있으므로 파일을 사용하여 파일 목록을 분류 할 수도 있습니다.
Hazok

11
최신 버전 find에서는 다음과 같이 쓸 수 있습니다. find . -name '*.foo' -exec cat {} +여기서는 단일 명령 호출에 편리한 수만큼 파일 이름을 그룹화해야 +함을 나타냅니다 find. 이것은 매우 유용합니다 ( -print0및에 의존하지 않고 파일 이름의 공백 등을 처리합니다 xargs -0).
Jonathan Leffler

18
언급되지 않은 :find . -name '*.foo' | xargs cat
stewSquared

3
@stewSquared 답변 추가 : 특정 문자열을 포함하는 파일의 모든 줄을 찾으려면find . -name '*.foo' | xargs cat | grep string
Bim

84

최신 버전

POSIX 2008은 +마커를 추가하여 find이제는 많은 수의 파일을 단일 명령 실행으로 합리적으로 많은 수의 파일을 자동으로 그룹화 xargs하지만 여러 가지 장점이 있습니다.

  1. 파일 이름의 홀수 문자에 대해 걱정할 필요가 없습니다.
  2. 파일 이름이 0 인 명령이 호출되는 것에 대해 걱정할 필요가 없습니다.

파일 이름 문제는 옵션 이 xargs없는 문제 -0이며, '제로 파일 이름으로도 실행'문제는 -0옵션의 유무에 관계없이 문제입니다. 그러나 GNU xargs에는이 를 방지하기위한 -r또는 --no-run-if-empty옵션이 있습니다. 또한이 표기법은 프로세스 수를 줄이며 성능의 차이를 측정하지는 않습니다. 따라서 현명하게 다음과 같이 쓸 수 있습니다.

find . -exec grep something {} +

클래식 버전

find . -print | xargs grep something

Linux를 사용 중이거나 GNU findxargs명령 이있는 경우 -print0with find-0with xargs를 사용 하여 공백 및 기타 홀수 문자가 포함 된 파일 이름을 처리하십시오.

find . -print0 | xargs -0 grep something

의 결과 조정 grep

파일 이름 (텍스트 만)을 원하지 않는 경우 적절한 옵션을 추가하십시오 grep(일반적 -h으로 '제목'억제). 파일 이름이 grep하나만 발견되거나 마지막 호출에 grep1 개의 파일 이름 만 지정된 경우에도 파일 이름이 인쇄 /dev/null되도록하려면 xargs명령 행에 추가 하여 항상 두 개 이상의 파일 이름을 갖도록하십시오.


나처럼 혼란스러워하는 사람들에게는이 방법으로 먼저 찾기의 모든 출력을 제공 한 다음의 출력을 제공합니다 xargs grep something.
Eric Hu

3
@EricHu : 혼란 스러울 수 있지만 적어도 내가 아는 유닉스 기반 시스템에서는 말하지 않습니다. 의 출력은 find의 표준 입력으로 파이프됩니다 xargs. xargs프로그램에 공백 (공백, 개행, 탭 등)의 입력을 분리하는, 표준 입력을 판독하고, 명령에 단어들을 추가 grep something및 커맨드 라인을 실행한다. xargs그런 다음 입력이 부족해질 때까지 입력을 계속 읽고 명령을 실행합니다. 주어진 입력에 필요한만큼 ( 이 예제에서) 명령을 xargs실행합니다 . grepfind
Jonathan Leffler 2013

아, 내 실수, 이것은 grep을 사용하여 일치하는 각 파일 내에서 검색합니다. grep으로 find의 출력을 간단히 필터링하려고했습니다
Eric Hu

1
오류는 올바르게 작동하는 모든 명령에서 표준 오류 (파일 설명자 2)로 이동합니다. stderr를 리디렉션 /dev/null하면 오류 메시지가 사라집니다.
Jonathan Leffler

1
또한 파일 경로의 공백으로 더 잘 작동한다는 이점이 있습니다. ""-> "\"조차도`와 함께
나누지

36

기술적으로 모든 파이프를 사용하는 것은 아니지만 실제로 직접 파이프하는 것은 아니지만 find명령에 의해 리턴 된 파일 목록을 명령 에 전달하는 몇 가지 방법이 cat있습니다 cat.

  1. 가장 간단한 방법은 백틱 ( `) 을 사용하는 것입니다 .

    cat `find [whatever]`
    

    이것의 출력을 가져 와서의 find명령 행에 효과적으로 배치합니다 cat. find출력이 너무 많거나 (명령 줄에 입력 할 수있는 것보다) 출력에 공백과 같은 특수 문자가있는 경우 에는 제대로 작동하지 않습니다 .

  2. 를 포함한 일부 쉘에서는 백틱 대신 bash사용할 수 있습니다 $().

    cat $(find [whatever])
    

    이식성이 떨어지지 만 중첩 가능합니다. 그 외에도 백틱과 거의 같은 경고가 있습니다.

  3. 찾은 내용에 대해 다른 명령을 실행하는 것이 일반적인 용도 find이므로 find에는 -exec찾은 각 파일에 대해 명령을 실행 하는 작업이 있습니다.

    find [whatever] -exec cat {} \;
    

    {}파일 이름에 대한 자리 표시 자이며, \;명령의 끝 마크 (그것은 가능 후 다른 작업을하기 위해 -exec.)

    이것은 여러 파일 이름을 전달 cat하는 단일 인스턴스를 실행하는 대신 모든 단일 파일에 대해 한 번 실행 cat되며 비효율적이며 일부 명령에 대해 원하는 동작을 수행하지 않을 수 있습니다 ( cat). 구문은 입력하기가 어색합니다. 세미콜론은 쉘에 특수하므로 세미콜론을 이스케이프해야합니다!

  4. 일부 버전 find(특히 GNU 버전)는 교체 할 수 ;+사용에 -exec적은 인스턴스를 실행할 수의 추가 모드 ' cat:

    find [whatever] -exec cat {} +
    

    이렇게하면 호출 할 때마다 여러 개의 파일 이름이 전달 cat되므로 더 효율적일 수 있습니다.

    그러나 이것이 단일 호출을 사용한다고 보장 되지않습니다 . 명령 행이 너무 길면 인수가 여러 번 호출됩니다 cat. 들어 cat이 아마 큰 문제가 아니지만, 다른 명령이 바람직하지 못한 방법으로 동작을 변경할 수 있습니다. Linux 시스템에서 명령 행 길이 한계는 상당히 크므로 여러 호출로 분할하는 것은 다른 OS와 비교할 때 매우 드 rare니다.

  5. 클래식 / 휴대용 접근 방식은 다음을 사용하는 것입니다 xargs.

    find [whatever] | xargs cat
    

    xargs지정된 명령 ( cat이 경우)을 실행하고 stdin에서 읽은 내용에 따라 인수를 추가합니다. 같은 단지 -exec+필요한 경우,이 명령 줄을 끊어집니다. 즉, find너무 많은 출력을 생성하면 cat여러 번 실행 됩니다. -exec이전 섹션에서 언급 했듯이이 분할로 인해 다른 동작이 발생할 수있는 명령이 있습니다. 공백을 구분 기호로 사용하는 xargs것처럼 이와 같이 사용 하면 파일 이름에 xargs공백이 생깁니다.

  6. 가장 강력하고 휴대 가능하며 효율적인 방법은 다음을 사용합니다 xargs.

    find [whatever] -print0 | xargs -0 cat
    

    -print0플래그는 말한다 find사용하는 \0파일 이름 사이에 (널 문자) 구분 기호를하고, -0플래그는 알 xargs이 기대하는 \0구분 기호를. 이 방법 은 -exec... +접근 방식 과 거의 동일한 동작을 하지만 더 이식 가능하지만 불행히도 더 장황합니다.


backtick 메소드는와 같은 다른 명령에서도 작동하기 때문에 훌륭합니다 ls.
마틴 브라운

@Martin Braun using $()이외의 명령에서도 작동합니다 find .
Laurence Gonsalves

고마워요, 알아두면 좋은 점은 공백과 같은 특수 문자를 다루지 않기 때문에 (1) 후에는 독서를 중단했습니다.
마틴 브라운

9

이것을 달성하려면 (bash를 사용하여) 다음과 같이하십시오.

cat $(find . -name '*.foo')

이것을 "명령 대체"라고하며 기본적으로 줄 바꿈을 제거합니다.

더 많은 정보는 여기에


6

나에게 쉘 스크립트 작업처럼 들린다.

for file in 'find -name *.xml'
do
   grep 'hello' file
done

또는 그런 것


2
이것은 반드시 최적의 것은 아니지만 질문에 대한 답입니다.
Jonathan Leffler

1
... 그렇지만 파일 이름이 나열된 큰 파일 하나를 원한다면 좋습니다.
ʍǝɥʇɐɯ

1
나는 이것을 가장 좋아한다. 이와 같은 루프 블록은 다른 작업을 수행 할 공간을 남겨 둡니다.
kakyo

4

다음은 내가 관심있는 내용이 들어있는 파일 이름을 찾는 방법입니다. 파일 이름의 공백도 잘 처리하는 단일 bash 줄입니다.

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done

3

나는 이와 같은 것을 사용한다 :

find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>

" -print0찾기"와 ""에 대한 인수는 " -0" "xargs를"에 대한 인수는 제대로 파일 경로 / 이름에 핸들 공백에 필요하다.



2

다음은 일반적인 사용을위한 샷입니다.

grep YOURSTRING `find .`

파일 이름을 인쇄합니다


2

bash에서는 다음이 적합합니다.

find /dir -type f -print0 | xargs -0i cat {} | grep whatever

이는 모든 파일을 찾을 /dir디렉토리 및 안전 관 파일 이름에 xargs안전 운전 것이다, grep.

xargs수천 개의 파일이있는 경우 건너 뛰는 것은 좋지 않습니다 /dir. cat인수 목록 길이가 너무 길면 중단됩니다. xargs당신을 위해 그 모든 것을 정렬합니다.

-print0에 인수 find와 메쉬 -0인수하는 xargs제대로 공백이있는 파일 이름을 처리합니다. 명령 행 에서 필요한 경우 파일 이름을 삽입 할 수 있는 -i인수 입니다. 대괄호는에서 명령으로 파이프 된 파일 이름으로 대체됩니다 .xargscatcatfind


0

이것은 나를 위해 작동

find _CACHE_* | while read line; do
    cat "$line" | grep "something"
done

0

ggrep을 사용하십시오 .

ggrep -H -R -I "mysearchstring" *

현재 디렉토리 또는 서브 디렉토리에있는 텍스트를 포함하는 유닉스에서 파일을 검색하려면


0

파일의 이름과 내용을 재귀 적으로 만 인쇄합니다.

find . -type f -printf '\n\n%p:\n' -exec cat {} \;

편집 (개선 된 버전) : 텍스트 (아스키) 파일의 이름과 내용을 재귀 적으로 만 인쇄합니다.

find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'

한 번 더 시도

find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;

-1

파일에서 텍스트를 찾으려고합니까? 당신은 단순히 grep을 사용할 수 있습니다 ...

grep searchterm *

-1

/ ghi 및 / jkl 디렉토리의 서버에있는 모든 abc.def 파일의 내용을 나열하고 보려면

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;

항목을 주석 처리하고 표시 한 abc.def 파일을 나열하려면 / ghi 및 / jkl 디렉토리의 해당 항목을 참조하십시오.

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.