답변:
다른 프로세스로 파이핑 (이 작업을 수행하려고했지만 달성하지는 못함) :
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
명령 이있는 경우 -print0
with find
및 -0
with xargs
를 사용 하여 공백 및 기타 홀수 문자가 포함 된 파일 이름을 처리하십시오.
find . -print0 | xargs -0 grep something
grep
파일 이름 (텍스트 만)을 원하지 않는 경우 적절한 옵션을 추가하십시오 grep
(일반적 -h
으로 '제목'억제). 파일 이름이 grep
하나만 발견되거나 마지막 호출에 grep
1 개의 파일 이름 만 지정된 경우에도 파일 이름이 인쇄 /dev/null
되도록하려면 xargs
명령 행에 추가 하여 항상 두 개 이상의 파일 이름을 갖도록하십시오.
xargs grep something
.
find
의 표준 입력으로 파이프됩니다 xargs
. xargs
프로그램에 공백 (공백, 개행, 탭 등)의 입력을 분리하는, 표준 입력을 판독하고, 명령에 단어들을 추가 grep something
및 커맨드 라인을 실행한다. xargs
그런 다음 입력이 부족해질 때까지 입력을 계속 읽고 명령을 실행합니다. 주어진 입력에 필요한만큼 ( 이 예제에서) 명령을 xargs
실행합니다 . grep
find
/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
인수 입니다. 대괄호는에서 명령으로 파이프 된 파일 이름으로 대체됩니다 .xargs
cat
cat
find
파일의 이름과 내용을 재귀 적으로 만 인쇄합니다.
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
는 나를 위해 위대한 일을 ... 감사합니다