답변:
이것은 예제와 함께 가장 잘 설명 될 수 있습니다. 다음 find
과 같은 파일 이 나타납니다.
file1
file2
file3
-exec
세미콜론 ( find . -exec ls '{}' \;
) 과 함께 사용하면
ls file1
ls file2
ls file3
그러나 더하기 부호 ( find . -exec ls '{}' \+
)를 대신 사용하면 가능한 한 많은 파일 이름이 단일 명령에 인수로 전달됩니다.
ls file1 file2 file3
파일 이름의 수는 시스템의 최대 명령 줄 길이에 의해서만 제한됩니다. 명령이이 길이를 초과하면 명령이 여러 번 호출됩니다.
+
관련 -exec
이 항상 이스케이프되었지만 +
관련 -mtime
이 없음을 알았습니다 . 이유를 아십니까? ;
과 관련하여 탈출하는 습관이 있다고 생각합니다 -exec
.
;
. 탈출해야한다고 상상할 수 없다+
지금까지의 모든 대답은 정확합니다. 내가 사용하여 설명되어있는 문제의 (나에게) 명확 시위로이 제공 echo
보다는 ls
:
세미콜론을 사용하면 echo
파일 (또는 다른 파일 시스템 객체)이 발견 될 때마다 명령 이 한 번 호출됩니다.
$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh
더하기 명령 echo
은 한 번만 호출됩니다. 발견 된 모든 파일은 인수로 전달됩니다.
$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh
find
많은 수의 결과가 나오면 호출되는 명령이 여러 개의 인수에서 질식되는 것을 알 수 있습니다.
xargs
... 원칙적으로 너무 많은 주장을 질식 시키지는 않는다.
find
(및 xargs
)는 소비 할 수있는 것보다 더 많은 인수를 내 보냅니다 . GNU findutils 의 xargs
(그리고 find
)는 더 현명하게 행동하는 것처럼 보이지만 모든 사람이 GNU를 사용하는 것은 아닙니다.
find
는 인수 수의 한계에 도달하지 않도록 시도합니다. 그리고 여기에는 Solaris가 포함됩니다 (적어도 10 개). 실패 할 수있는 곳은 find ... -exec ksh -c 'cmd "$@" "$@"' sh {} +
또는 과 같은 것을 find ... -exec ksh -c 'files="$*" cmd "$@"' sh {} +
하지만 find
실제로는 그것을 비난 할 수 없습니다. GNU find
는 find
지원을위한 마지막 구현 중 하나입니다 +
(스크립트를 GNU 시스템으로 이식하는 데 어려움을 겪었 음).
보낸 사람 man find
:
-exec 명령;
명령을 실행하십시오. 0 상태가 반환되면 true입니다. 찾을 다음의 모든 인수는 ';'로 구성된 인수까지 명령에 대한 인수로 간주됩니다. 발생합니다. 문자열 '{}'은 (는) 일부 버전의 find에서와 같이 단독 인수가 아닌 명령 인수에서 발생하는 모든 위치에서 처리되는 현재 파일 이름으로 바뀝니다. 이 두 구조는 모두 쉘에서 확장되는 것을 막기 위해 이스케이프 처리 ( '\')하거나 인용해야합니다. '-exec'옵션 사용의 예는 EXAMPLES 섹션을 참조하십시오. 지정된 명령은 일치하는 각 파일마다 한 번씩 실행됩니다. 명령은 시작 디렉토리에서 실행됩니다. -exec 옵션 사용과 관련하여 피할 수없는 보안 문제가 있습니다.
-exec 명령 {} +
-exec 옵션의이 변형은 선택된 파일에서 지정된 명령을 실행하지만 명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다 . 명령의 총 호출 수는 일치하는 파일 수보다 훨씬 적습니다. 명령 행은 xargs가 명령 행을 빌드하는 것과 거의 같은 방식으로 빌드됩니다. 명령 내에서 하나의 '{}'인스턴스 만 허용됩니다. 명령은 시작 디렉토리에서 실행됩니다.
따라서 내가 이해하는 방식 \;
은에서 찾은 각 파일에 대해 별도의 명령을 실행하는 find
반면 \+
파일을 추가하고 모든 파일에 대해 단일 명령을 실행합니다. 는 \
이 그래서, 이스케이프 문자입니다 :
ls testdir1; ls testdir2
vs
ls testdir1 testdir2
내 셸에서 위의 작업을 수행하면 질문의 출력이 반영됩니다.
\+
두 파일을 가정, 1.tmp
그리고 2.tmp
:
1.tmp :
1
2
3
2.tmp :
0
2
3
로 \;
:
find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.
를 사용하는 경우 \+
(의 결과를 연결하기 위해 find
) :
find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30
따라서이 경우에는 사이의 차이점 diff 1.tmp; diff 2.tmp
과diff 1.tmp 2.tmp
여기서 경우가 있습니다 \;
적절한 지와 \+
필요합니다. \+
with를 사용하면 rm
많은 파일을 제거하는 경우 성능 (속도)이보다 우수합니다 \;
.
find
특별한 구문이 있습니다. {}
찾은 파일의 경로 이름으로 찾을 의미가 있기 때문에 그대로 사용 하고 (대부분) 셸은 다른 방식으로 해석하지 않습니다. \;
세미콜론은 쉘에 의미가 있기 때문에 백 슬래시가 필요합니다 find
. 따라서 find
C 프로그램에 전달 된 인수 목록에서 쉘이 완료된 후보고 싶은 것은
"-exec", "rm", "{}", ";"
그러나 \;
쉘을 통해 인수에 세미콜론을 가져 오려면 명령 행에 필요 합니다.
\{\}
쉘 인용 해석 \{\}
이 그냥 있기 때문에 벗어날 수 있습니다 {}
. 마찬가지로 '{}'을 (를) 사용할 수 있습니다.
당신이 할 수없는 것은 사용입니다
-exec 'rm {} ;'
쉘은 이것을 하나의 인수 로 해석하기 때문에
"-exec", "rm {};"
및 rm {} ;
명령의 이름이 아닙니다. (적어도 누군가가 정말로 조이고 있지 않는 한)
최신 정보
차이점은
$ ls file1
$ ls file2
과
$ ls file1 file2
는 +
명령 줄에 이름을 catenating된다.
;
(세미콜론) 또는 +
(더하기 부호) 의 차이점 은 인수가 find의 -exec
/ -execdir
매개 변수 로 전달되는 방식 입니다. 예를 들면 다음과 같습니다.
using ;
은 여러 명령을 실행합니다 (각 인수마다 별도로).
예:
$ find /etc/rc* -exec echo Arg: {} ';'
Arg: /etc/rc.common
Arg: /etc/rc.common~previous
Arg: /etc/rc.local
Arg: /etc/rc.netboot
다음의 모든 인수
find
는 명령에 대한 인수로 간주됩니다.문자열
{}
은 처리중인 현재 파일 이름으로 바뀝니다.
를 사용 +
하면 가능한 최소한의 명령이 실행됩니다 (인수가 결합되어 있기 때문에). xargs
명령의 작동 방식과 매우 유사 하므로 한 줄에 최대 인수 제한을 초과하지 않도록 명령 당 가능한 많은 인수를 사용합니다.
예:
$ find /etc/rc* -exec echo Arg: {} '+'
Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다.
{}
명령 내에서 하나의 인스턴스 만 허용됩니다.
또한보십시오: