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

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

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

내 디렉터리에 다음 콘텐츠가 있다고 가정해 보겠습니다.

$ ls
file1 file2 file3 file4 file5 dir1 dir2 dir3

하나의 명령으로 모든 디렉토리의 모든 파일을 복사하고 싶습니다. 나는 이전에 시도했습니다:

 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을 구분 기호로 사용하고 한 번에 하나의 인수로만 시작합니다.

답변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

관련 정보