![find를 다른 명령과 결합: 언제 -exec를 사용하고 언제 파이프를 사용합니까? [복사]](https://linux55.com/image/57158/find%EB%A5%BC%20%EB%8B%A4%EB%A5%B8%20%EB%AA%85%EB%A0%B9%EA%B3%BC%20%EA%B2%B0%ED%95%A9%3A%20%EC%96%B8%EC%A0%9C%20-exec%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B3%A0%20%EC%96%B8%EC%A0%9C%20%ED%8C%8C%EC%9D%B4%ED%94%84%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%A9%EB%8B%88%EA%B9%8C%3F%20%5B%EB%B3%B5%EC%82%AC%5D.png)
파일과 디렉터리를 찾기 위해 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
발견된 항목 수만큼 명령을 호출합니다.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.