find를 다른 명령과 결합: 언제 -exec를 사용하고 언제 파이프를 사용합니까? [복사]

find를 다른 명령과 결합: 언제 -exec를 사용하고 언제 파이프를 사용합니까? [복사]

파일과 디렉터리를 찾기 위해 find 명령 자체를 사용하는 방법을 배웠지만, 파일/폴더에 대한 특정 작업을 수행할 때 혼란스럽습니다.

다음 명령을 내리세요:

find . -type f -iname "*.cr2" 

위에서 찾은 파일을 새 디렉터리에 복사하려면 자연스럽게 copy( cp) 및 파이프라인을 사용하는 방법을 생각할 것입니다 |.

find . -type f -iname "*.cr2" | cp \destination_directory

제 경우에는 하위 폴더 수준이 하나의 폴더에 중첩되어 전체 드라이브에 모든 사진이 저장되어 정리를 시작할 수 있습니다.

그러나 사람들은 계속해서 매개 변수를 사용하라고 말합니다 . 그래서 제 질문은 언제 파이프를 사용해야 하는지, 언제 이와 같은 명령을 사용해야 하는지 -exec어떻게 알 수 있느냐는 것입니다 .|-exec

 find . -name "*.pdf" -type f -exec cp {} ./pdfsfolder \;

편집하다

아래 제안된 솔루션은 고유한 파일 이름을 가진 파일만 복사합니다. cp는 file.txt를 복사하지 않고 file.txt로 바꾸지 않을 것이라고 말합니다. 파일을 많이 복사했는데 같은 이름의 파일이 있을지 모르는 경우, 일부 파일을 복사하고 파일 이름이 있으면 어떻게 이름을 바꾸나요?

제안된 솔루션

find . -type f -iname "*.txt" -print0 | xargs -0 cp -t /home/josh/Documents/copy/

/home/josh/documents/copy는 콘텐츠를 이동하려는 디렉터리입니다.

답변1

귀하의 가정은 틀렸지만 먼저 몇 가지 배경 정보가 있습니다.

식별해야 할 두 가지 용도는 다음과 같습니다 -exec.

  • 발견된 단일 \;항목 으로 대체됩니다.{}
  • 명령줄이 수용할 수 있는 만큼의 +항목 으로 대체됩니다 .{}

따라서 사용 예에서는 -exec발견된 항목 수만큼 명령을 호출합니다.cpfind

사용 find ... -exec cmd {} ... +효율성은 find의 출력을 여러 입력 이름을 처리하는 명령으로 파이프하는 것과 유사합니다.

-exec또한 공백이 있는 파일 이름/경로는 잘 처리되지만 find의 출력을 다른 프로그램으로 파이프할 때 문제가 발생할 수 있다는 점을 고려해야 합니다 . 따라서 stdin의 파일 이름 목록이 필요한 일부 프로그램은 파일 이름을 NUL(보통 -0또는 --null)로 구분하도록 선택할 수 있습니다. find다음을 지정하여 선택적으로 다음 프로그램에 제공할 수 있습니다 .-print0


이제 귀하의 예를 살펴보십시오.

find . -type f -iname "*.cr2" | cp destination_directory

cp가 표준 입력에서 읽지 않기 때문에 발견된 파일은 복사되지 않습니다. 다음을 사용해야 합니다.

find . -type f -iname "*.cr2" | xargs cp -t destination_directory

또는 공백이 있는 경로를 처리합니다.

find . -type f -iname "*.cr2" -print0 | xargs -0 cp -t destination_directory

거의 동일한 효율성으로 다음 작업을 수행할 수 있습니다.

find . -type f -iname "*.cr2" -exec cp -t destination_directory {} +

( G-Man이 지적한 것처럼 {}마지막에 있어야 함 +) 위의 모든 내용이 적용됩니다.아니요이를 위해 대상 디렉터리 아래에 계층 구조를 구축하고 오랜 습관에 따라 소스 디렉터리가 단순하더라도 다음을 사용합니다 cpio.

find . -type f -iname "*.cr2" -print0 | cpio -pdmv0 destination_directory

그 과정에서 수행한 작업을 잘 설명합니다.


관련 부품 man find:

-exec command ;
       Execute command; true if 0 status is returned.   All  following
       arguments  to  find  are  taken  to be arguments to the command
       until an argument consisting of `;' is encountered.  The string
       `{}'  is  replaced  by  the  current  file name being processed
       everywhere it occurs in the arguments to the command, not  just
       in  arguments  where  it is alone, as in some versions of find.
       Both of these constructions might need to be  escaped  (with  a
       `\')  or  quoted  to  protect them from expansion by the shell.
       See the EXAMPLES section for examples of the use of  the  -exec
       option.   The  specified  command  is run once for each matched
       file.  The command  is  executed  in  the  starting  directory.
       There  are unavoidable security problems surrounding use of the
       -exec action; you should use the -execdir option instead.

-exec command {} +
       This variant of the -exec action runs the specified command  on
       the  selected files, but the command line is built by appending
       each selected file name at the end; the total number of invoca‐
       tions  of  the  command  will  be  much less than the number of
       matched files.  The command line is built in much the same  way
       that xargs builds its command lines.  Only one instance of `{}'
       is allowed within the command.  The command is executed in  the
       starting directory.

관련 정보