변수 확장을 사용하여 bash 스크립트에서 -exec 찾기

변수 확장을 사용하여 bash 스크립트에서 -exec 찾기

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-플래그에도 의존합니다.

shTechZilla는 물론 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 \;

관련 정보