"find / -name '*.txt' | cp /junk"가 작동하지 않는 이유는 무엇입니까?

"find / -name '*.txt' | cp /junk"가 작동하지 않는 이유는 무엇입니까?

이름에 .txt가 포함된 파일을 찾고 발견된 각 일치 항목에 대해 /junk 폴더에 복사하려면 다음 방법을 사용하는 것이 좋습니다.

find / -name "*.txt" | cp /junk

그러나 find는 목록 형태로 결과를 생성하고 해당 목록을 cp에 입력할 수 없기 때문에 이것은 작동하지 않습니다.

따라서 xargs를 사용하여 이 문제를 해결할 수 있습니다.

find / -name "*.txt" | xargs cp /junk

xargs는 목록을 한 줄로 변경하므로 cp에 입력할 수 있습니다. 나는 또한 이 명령이 파일 검색을 완전히 완료하고 "목록 만들기"를 완료한 다음에만 파이프라인의 오른쪽(복사본)을 실행할 것이라고 생각했습니다.

또는 (바람직하게는) exec를 사용할 수 있습니다.

find / -name ".txt" -exec cp {} /junk \;

일치하는 항목이 발견될 때마다 복사본이 실행됩니다(별도의 프로세스에서 실행되므로 find 명령은 계속해서 병렬로 실행됩니다).

누군가 이 명령과 나의 이해가 올바른지 확인할 수 있습니까?

이것은 교육 목적일 뿐이며 실제 시나리오가 아니라는 점을 덧붙이고 싶습니다.

답변1

  1. 예, 표준 입력에서 인수를 읽지 않으므로 find / -name "*.txt" | cp /junk작동하지 않습니다 .cp
  2. 아니요, stdin에서 읽은 인수가 명령에 추가되어 잘못된 방향으로 복사하려고 하기 find / -name "*.txt" | xargs cp /junk때문에 그것도 작동하지 않습니다 . (옵션을 사용하여 문제를 해결할 수 있지만 간단히 를 사용할 수도 있습니다 .)xargscp-Ixargsfind -exec
  3. 예, find / -name ".txt" -exec cp {} /junk \;작동합니다. 하지만 파일당 한 번의 호출을 사용합니다 cp(그리고 파일을 찾으면 명령이 실행됩니다).

이 솔루션을 시도해 볼 수도 있습니다. 단 한 번의 호출만 시작해야 합니다 cp(또는 최소한 제한된 명령줄 길이로 가능한 적은 호출을 시작합니다).

find / -path /junk -prune -or -name '*.txt' -print0 | xargs -0 sh -c 'cp "$@" /junk'

cp -t@don_chrissti가 언급했듯이 GNU cp가 있으면 사용할 수 있습니다. 그럼 당신은 이것을 할 수 있습니다

find / -path /junk -prune -or -name '*.txt' -print0 | xargs -0 cp -t /junk

심지어

find / -path /junk -prune -or -name '*.txt' -exec cp -t /junk {} +

세 가지 모두 명령줄에서 가능한 한 많은 인수를 수집하고 가능한 한 적은 수의 인스턴스를 실행합니다 cp. 그러나 cpa가 완료되기 전에 시작될 가능성은 여전히 ​​있으므로 find이를 제외해야 합니다. /junk그렇지 않으면 복사본을 찾을 수 있습니다.

관련 정보