파일과 디렉토리를 찾기 위해 find 명령을 단독으로 사용하는 방법을 배웠습니다. 그러나 파일/폴더로 작업을 수행할 때 혼란스럽습니다.
다음 명령이 주어졌습니다.
find . -type f -iname "*.cr2"
위에서 찾은 파일을 새 디렉터리에 복사하려면 당연히 copy( cp
) 및 Pipe를 사용한다고 생각합니다 |
.
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
많은 명령을 호출합니다 .cp
find
사용은 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.