[find] 찾기에서 exec와 함께 세미콜론 (;) 대 더하기 (+) 사용

사용시 출력에 차이가있는 이유

find . -exec ls '{}' \+

find . -exec ls '{}' \;

나는 얻었다 :

$ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1



답변

이것은 예제와 함께 가장 잘 설명 될 수 있습니다. 다음 find과 같은 파일 이 나타납니다.

file1
file2
file3

-exec세미콜론 ( find . -exec ls '{}' \;) 과 함께 사용하면

ls file1
ls file2
ls file3

그러나 더하기 부호 ( find . -exec ls '{}' \+)를 대신 사용하면 가능한 한 많은 파일 이름이 단일 명령에 인수로 전달됩니다.

ls file1 file2 file3

파일 이름의 수는 시스템의 최대 명령 줄 길이에 의해서만 제한됩니다. 명령이이 길이를 초과하면 명령이 여러 번 호출됩니다.


답변

지금까지의 모든 대답은 정확합니다. 내가 사용하여 설명되어있는 문제의 (나에게) 명확 시위로이 제공 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많은 수의 결과가 나오면 호출되는 명령이 여러 개의 인수에서 질식되는 것을 알 수 있습니다.


답변

보낸 사람 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.tmpdiff 1.tmp 2.tmp

여기서 경우가 있습니다 \;적절한 지와 \+필요합니다. \+with를 사용하면 rm많은 파일을 제거하는 경우 성능 (속도)이보다 우수합니다 \;.


답변

find특별한 구문이 있습니다. {}찾은 파일의 경로 이름으로 찾을 의미가 있기 때문에 그대로 사용 하고 (대부분) 셸은 다른 방식으로 해석하지 않습니다. \;세미콜론은 쉘에 의미가 있기 때문에 백 슬래시가 필요합니다 find. 따라서 findC 프로그램에 전달 된 인수 목록에서 쉘이 완료된 후보고 싶은 것은

“-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
    

    명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다.

    {}명령 내에서 하나의 인스턴스 만 허용됩니다.

또한보십시오:


답변

하우스 키핑을위한 파일을 찾으려고했습니다.

찾기 . -exec echo {} \; 명령 결과는 결국 밤새 실행되었습니다.

찾기 . -exec echo {} \ + 결과가 있으며 몇 시간 밖에 걸리지 않았습니다.

도움이 되었기를 바랍니다.


답변