답변:
다른 프로세스로 파이핑 (이 작업을 수행하려고했지만 달성하지는 못함) :
command1 | command2
이것은 command1의 출력을 command2의 입력으로 보냅니다.
-exec에 find(이것은 당신이하고 싶은 일을 할 것입니다-그러나 특정합니다 find)
find . -name '*.foo' -exec cat {} \;
( 이미 사용하고있는 find 술어 사이 find와. 사이에있는 모든 것은 명령에서 찾은 특정 파일 ( 이 경우) 을 대체합니다 -exec. {}명령 을 종료하는 것 입니다.)cat {}\;-exec
한 프로세스의 출력을 다른 프로세스에 명령 행 인수로 전송
command2 `command1`
예를 들면 다음과 같습니다.
cat `find . -name '*.foo' -print`
(이것은 정규 인용 부호가 아닌 BACK-QUOTES입니다 (내 키보드의 물결표 ~ 아래에 있음). 이것은 명령 줄 인수 command1로 출력을 보냅니다 command2. 그러나 공백 (줄 바꾸기 등)이 포함 된 파일 이름은 별도의 인수로 구분됩니다.
find에서는 다음과 같이 쓸 수 있습니다. find . -name '*.foo' -exec cat {} +여기서는 단일 명령 호출에 편리한 수만큼 파일 이름을 그룹화해야 +함을 나타냅니다 find. 이것은 매우 유용합니다 ( -print0및에 의존하지 않고 파일 이름의 공백 등을 처리합니다 xargs -0).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008은 +마커를 추가하여 find이제는 많은 수의 파일을 단일 명령 실행으로 합리적으로 많은 수의 파일을 자동으로 그룹화 xargs하지만 여러 가지 장점이 있습니다.
파일 이름 문제는 옵션 이 xargs없는 문제 -0이며, '제로 파일 이름으로도 실행'문제는 -0옵션의 유무에 관계없이 문제입니다. 그러나 GNU xargs에는이 를 방지하기위한 -r또는 --no-run-if-empty옵션이 있습니다. 또한이 표기법은 프로세스 수를 줄이며 성능의 차이를 측정하지는 않습니다. 따라서 현명하게 다음과 같이 쓸 수 있습니다.
find . -exec grep something {} +
find . -print | xargs grep something
Linux를 사용 중이거나 GNU find및 xargs명령 이있는 경우 -print0with find및 -0with xargs를 사용 하여 공백 및 기타 홀수 문자가 포함 된 파일 이름을 처리하십시오.
find . -print0 | xargs -0 grep something
grep파일 이름 (텍스트 만)을 원하지 않는 경우 적절한 옵션을 추가하십시오 grep(일반적 -h으로 '제목'억제). 파일 이름이 grep하나만 발견되거나 마지막 호출에 grep1 개의 파일 이름 만 지정된 경우에도 파일 이름이 인쇄 /dev/null되도록하려면 xargs명령 행에 추가 하여 항상 두 개 이상의 파일 이름을 갖도록하십시오.
xargs grep something.
find의 표준 입력으로 파이프됩니다 xargs. xargs프로그램에 공백 (공백, 개행, 탭 등)의 입력을 분리하는, 표준 입력을 판독하고, 명령에 단어들을 추가 grep something및 커맨드 라인을 실행한다. xargs그런 다음 입력이 부족해질 때까지 입력을 계속 읽고 명령을 실행합니다. 주어진 입력에 필요한만큼 ( 이 예제에서) 명령을 xargs실행합니다 . grepfind
/dev/null하면 오류 메시지가 사라집니다.
기술적으로 모든 파이프를 사용하는 것은 아니지만 실제로 직접 파이프하는 것은 아니지만 find명령에 의해 리턴 된 파일 목록을 명령 에 전달하는 몇 가지 방법이 cat있습니다 cat.
가장 간단한 방법은 백틱 ( `) 을 사용하는 것입니다 .
cat `find [whatever]`
이것의 출력을 가져 와서의 find명령 행에 효과적으로 배치합니다 cat. find출력이 너무 많거나 (명령 줄에 입력 할 수있는 것보다) 출력에 공백과 같은 특수 문자가있는 경우 에는 제대로 작동하지 않습니다 .
를 포함한 일부 쉘에서는 백틱 대신 bash사용할 수 있습니다 $().
cat $(find [whatever])
이식성이 떨어지지 만 중첩 가능합니다. 그 외에도 백틱과 거의 같은 경고가 있습니다.
찾은 내용에 대해 다른 명령을 실행하는 것이 일반적인 용도 find이므로 find에는 -exec찾은 각 파일에 대해 명령을 실행 하는 작업이 있습니다.
find [whatever] -exec cat {} \;
은 {}파일 이름에 대한 자리 표시 자이며, \;명령의 끝 마크 (그것은 가능 후 다른 작업을하기 위해 -exec.)
이것은 여러 파일 이름을 전달 cat하는 단일 인스턴스를 실행하는 대신 모든 단일 파일에 대해 한 번 실행 cat되며 비효율적이며 일부 명령에 대해 원하는 동작을 수행하지 않을 수 있습니다 ( cat). 구문은 입력하기가 어색합니다. 세미콜론은 쉘에 특수하므로 세미콜론을 이스케이프해야합니다!
일부 버전 find(특히 GNU 버전)는 교체 할 수 ;와 +사용에 -exec적은 인스턴스를 실행할 수의 추가 모드 ' cat:
find [whatever] -exec cat {} +
이렇게하면 호출 할 때마다 여러 개의 파일 이름이 전달 cat되므로 더 효율적일 수 있습니다.
그러나 이것이 단일 호출을 사용한다고 보장 되지 는 않습니다 . 명령 행이 너무 길면 인수가 여러 번 호출됩니다 cat. 들어 cat이 아마 큰 문제가 아니지만, 다른 명령이 바람직하지 못한 방법으로 동작을 변경할 수 있습니다. Linux 시스템에서 명령 행 길이 한계는 상당히 크므로 여러 호출로 분할하는 것은 다른 OS와 비교할 때 매우 드 rare니다.
클래식 / 휴대용 접근 방식은 다음을 사용하는 것입니다 xargs.
find [whatever] | xargs cat
xargs지정된 명령 ( cat이 경우)을 실행하고 stdin에서 읽은 내용에 따라 인수를 추가합니다. 같은 단지 -exec에 +필요한 경우,이 명령 줄을 끊어집니다. 즉, find너무 많은 출력을 생성하면 cat여러 번 실행 됩니다. -exec이전 섹션에서 언급 했듯이이 분할로 인해 다른 동작이 발생할 수있는 명령이 있습니다. 공백을 구분 기호로 사용하는 xargs것처럼 이와 같이 사용 하면 파일 이름에 xargs공백이 생깁니다.
가장 강력하고 휴대 가능하며 효율적인 방법은 다음을 사용합니다 xargs.
find [whatever] -print0 | xargs -0 cat
-print0플래그는 말한다 find사용하는 \0파일 이름 사이에 (널 문자) 구분 기호를하고, -0플래그는 알 xargs이 기대하는 \0구분 기호를. 이 방법 은 -exec... +접근 방식 과 거의 동일한 동작을 하지만 더 이식 가능하지만 불행히도 더 장황합니다.
ls.
$()이외의 명령에서도 작동합니다 find .
나에게 쉘 스크립트 작업처럼 들린다.
for file in 'find -name *.xml'
do
grep 'hello' file
done
또는 그런 것
find 명령에는 -exec 인수를 사용하여 이와 같은 작업에 사용할 수 있습니다. grep을 사용하여 직접 grep을 수행 할 수 있습니다.
예를 들어 ( 여기 에서이 페이지의 다른 좋은 예 ) :
find . -exec grep "www.athabasca" '{}' \; -print
bash에서는 다음이 적합합니다.
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
이는 모든 파일을 찾을 /dir디렉토리 및 안전 관 파일 이름에 xargs안전 운전 것이다, grep.
xargs수천 개의 파일이있는 경우 건너 뛰는 것은 좋지 않습니다 /dir. cat인수 목록 길이가 너무 길면 중단됩니다. xargs당신을 위해 그 모든 것을 정렬합니다.
-print0에 인수 find와 메쉬 -0인수하는 xargs제대로 공백이있는 파일 이름을 처리합니다. 명령 행 에서 필요한 경우 파일 이름을 삽입 할 수 있는 -i인수 입니다. 대괄호는에서 명령으로 파이프 된 파일 이름으로 대체됩니다 .xargscatcatfind
파일의 이름과 내용을 재귀 적으로 만 인쇄합니다.
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 {} \;
find -name '*.foo' -print는 나를 위해 위대한 일을 ... 감사합니다