Bash 스크립트에서 아래와 유사한 명령을 실행하려고 합니다. 모든 하위 폴더를 검색 $sourcedir
하고 특정 유형의 모든 파일을 루트 수준으로 복사해야 합니다 $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
전달 {}
되지 않는다는 점을 제외하면 꽤 가까운 것 같습니다.$2
-exec sh -c ...
나는 가능한 한 "올바른 방법"에 가까워지고 파일 이름의 특수 문자(특히 작은따옴표 문자)를 허용하고 싶습니다.
편집하다:xargs
누군가가 매개변수 체인 사용을 제안하는 것을 보았습니다 . 내 생각에는 이것이 제한된 수의 매개변수에서만 작동한다는 것입니다. 예를 들어, 여러 갤러리 디렉토리에서 거대한 슬라이드쇼 디렉토리로 복사하려는 수천 개의 .jpg 파일이 있는 경우 링크 매개변수 솔루션이 계속 작동합니까?
편집 2:_
내 문제는 명령의 첫 번째 옵션 sh 앞에 a가 없다는 것입니다 -exec
. find 명령을 작동시키는 방법에 대해 궁금한 사람은 다음을 추가하면 _
모든 것이 잘 될 것입니다.
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
아래 답변은 동일한 작업을 수행하지만 더 효율적이고 우아하기 때문에 수락했습니다.
답변1
특정 유형의 파일을 특정 디렉터리에 복사하시겠습니까? 이렇게 하는 것이 더 낫고 xargs
필요하지도 않습니다 sh
. 이는 보다 적절한 접근 방식이며 보다 효율적으로 실행되어야 합니다.
find "$sourcedir" -type f -name "*.type" | xargs cp -t targetdir
특수 파일 이름을 처리해야 하는 경우 NULL
구분 기호로 사용
find "$sourcedir" -type f -name "*.type" -print0 | xargs -0 cp -t "$targetdir"
답변2
{}
이를 쉘에 인수로 전달한 다음 각 인수를 반복 해야 합니다 .
find "$sourcedir" -type f -name "*.type" -exec sh -c 'for f; do cp "$f" "$0"; done' "$targetdir" {} +
노트: 작동 방식은 쉘에 대한 첫 번째 인수가 다음과 같다는 것입니다.쉘 이름, 이름을 로 전달한 다음 쉘 스크립트의 특수 매개변수를 사용하여 해당 대상 디렉토리에 액세스함으로써 $targetdir
이를 활용할 수 있습니다.$0
답변3
xargs 교회를 믿지 않는다면:
find "$sourcedir" -type f -name "*.mp3" -exec cp -t "$targetdir" {} +
설명하다:
cp -t a b c d
b, c, d를 대상 디렉터리 a에 복사합니다.
-exec cmd {} +
차례로 명령을 호출하는 것이 아니라 한 번에 여러 파일에 대해 명령을 호출합니다( ";"
대신 을 사용하는 경우 표준임 +
). 이것이 바로 우리가 targetdir을 앞으로 끌어와 명시적으로 대상으로 표시해야 하는 이유입니다.
이는 gnu-find에서는 작동하지만 다른 find 구현에서는 작동하지 않을 수 있습니다. 물론 -t-플래그에도 의존합니다.
sh
TechZilla는 물론 cp를 호출할 필요가 없기 때문에 맨 오른쪽에 있습니다 .
를 사용하지 않고 xargs
대부분의 경우 와 결합할 필요가 없다면 배우고 플래그를 지정할 find
필요가 없습니다 .-print0
-0
답변4
read -p "SOURCE: " sourcedir
read -p "TYPE: " type
read -p "TARGET: " targetdir
find -L $sourcedir -iname "*.$type" -exec cp -v {} $targetdir \;