여러 파일을 여러 디렉터리에 복사

여러 파일을 여러 디렉터리에 복사

다른 디렉토리에 많은 파일을 복사하는 데 문제가 있습니다. 더 잘 설명하겠습니다.

디렉토리에 다음이 있다고 가정해 보겠습니다.

$ ls
file1 file2 file3 file4 file5 dir1 dir2 dir3

단일 명령으로 모든 dir*의 모든 파일*을 복사하고 싶습니다. 나는 다음을 시도했습니다.

 echo dir{1..3} | xargs cp file{1..5} '{}' \;

내 의도는 xargs에게 echo의 모든 단일 dir*을 처리하고 처리된 입력의 모든 파일을 복사하도록 지시하는 것이었지만 이와 유사한 작업은 작동하지 않았습니다. 스크립트 사용은 피하고 싶습니다. 약 20개의 디렉터리에 대해 반복해야 하는 작업이고 파일 이름이 약간 다르기 때문에 스크립트보다는 명령을 수정하는 것을 선호합니다.

답변1

echo dir[1-3] | xargs -r -n1 cp file[1-5]

답변2

xargs 사용에 작은 실수가 있습니다. -n 매개변수가 없으면 xargs는 입력의 모든 매개변수를 명령에 추가하고 echo dir{1..3}각 항목 사이에 필요한 캐리지 리턴을 추가하지 않으므로 xargs는 결과를 하나의 매개변수로 간주합니다.

xargs에는 항목 수를 제한할 수 있는 -n 옵션이 있으며 \n 또는 \0을 구분 기호로 사용하여 디렉터리를 나열해야 합니다.

find . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 -n 1 cp file{1..5}

find 명령은 현재 디렉토리의 모든 디렉토리를 찾고 \0을 구분 기호로 사용하며(공백이 있는 디렉토리가 있는 경우 더 잘 작동함) xargs는 \0을 구분 기호로 사용하고 매개변수가 1개만 있을 때마다 명령을 실행합니다.

답변3

실제로 그러한 이름이 있는 경우 다음과 같은 작업이 작동합니다.

#!/bin/bash
shopt -s nullglob
for dir in dir*/; do
    cp file* "$dir"
done

이름에 관계없이 모든 파일을 모든 디렉토리에 복사하려면 다음을 수행하십시오.

#!/bin/bash
shopt -s nullglob dotglob
for dir in */; do
    for file in *; do
        [[ -f $file ]] && cp "$file" "$dir"
    done
done

답변4

거의 다 왔습니다. 모든 소스 파일의 복사본을 하나만 만들기 cp때문에 각 대상 디렉터리에 대해 별도의 명령을 실행해야 합니다 . cp의 주요 목적은 xargs여러 인수에 대해 하나의 명령을 실행하는 것이지만 옵션을 사용하면 한 번에 하나의 항목을 전달하도록 지시할 수 있습니다 -n. 또한 {} ;구문은 find … -exec; 와 함께 사용할 필요도 없고 사용할 수도 없습니다 xargs.

echo dir{1..3} | xargs -n 1 cp file{1..5}

이는 디렉토리 이름에 공백이나 문자가 포함되지 않은 경우에만 작동합니다 \'". 왜냐하면 xargs해당 문자가 파일 이름의 일부이고 입력 파일을 인용하거나 구분하지 않는다는 것을 알 수 있는 방법이 없기 때문입니다. 이러한 문제가 없는 대체 방법은 쉘 루프를 사용하는 것입니다.

for d in dirs{1..3}; do
  cp file{1..5} "$d"
done

이 모든 것은 파일과 디렉터리를 이름으로 쉽게 구별할 수 있다고 가정합니다. 일치하지 않는 경우 /끝에 를 추가하여 디렉터리를 일치시킬 수 있습니다. 예를 들어 */현재 디렉터리의 모든 디렉터리와 일치하고 foo[0-9]*/이름이 숫자 등으로 시작하는 모든 디렉터리와 일치합니다 foo. 대부분의 셸에서 디렉터리가 아닌 항목만 일치시키는 비슷한 방법은 없지만 cp인수 없이 디렉터리를 에 전달하면 알 수 있습니다. 재귀 복사본을 만들려면 오류 메시지와 함께 디렉터리가 무시됩니다.

for d in */; do
  cp * "$d"
done

zsh에서는 다음을 사용할 수 있습니다.글로벌 한정자특정 파일 형식만 일치시키려면

for d in *(/); do
  cp *(.) $d
done

관련 정보