한 폴더에서 다른 폴더로 여러 특정 파일 복사


133

사진 (수천 개)의 큰 폴더가 있으며 정확한 파일 이름으로 다른 폴더로 복사해야하는 긴 파일 목록이 있습니다. 이름 으로이 폴더에서 여러 특정 파일을 선택하고 터미널을 사용하여 개별 폴더로 복사하지 않고 다른 폴더로 복사 할 수있는 방법이 있는지 알고 싶습니다.


참고로 특정 폴더를 복사하려면 다음을 사용하십시오. cp -rp /copying/from/{folder1/,folder2/,folder3/} path/to/folder, 여기서 p폴더 권한을 복사합니다.
Raktim Biswas는

답변:


179

명령 줄에서 여러 파일을 한 번에 복사하기 만하면됩니다

이를 달성 할 수있는 몇 가지 방법이 있습니다. 내가 본 가장 쉬운 것은 다음을 사용하는 것입니다.

cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination/

구문은 cp 명령과 원하는 파일이있는 디렉토리의 경로를 괄호로 묶고 쉼표로 구분하여 복사하려는 모든 파일과 함께 사용합니다.

파일 사이에 공백이 없어야합니다. 명령의 마지막 부분은 /home/usr/destination/파일을 복사 할 디렉토리입니다.

또는 모든 파일의 접두사가 같지만 엔딩이 다른 경우 다음과 같이 할 수 있습니다.

cp /home/usr/dir/file{1..4} ./

file1, file2, file3 및 file4가 복사되는 위치

당신이 그 질문을 어떻게 말했는지에 따르면 이것이 당신이 찾고있는 것이라고 생각하지만 파일 목록에서 읽고 모든 디렉토리를 특정 디렉토리에 복사하는 명령을 찾고있는 것처럼 들립니다. 이 경우 알려 주시면 답변을 수정하겠습니다.

파이썬으로 중복 다루기

그래서 나는 일을 끝내야한다고 생각하는 작은 파이썬 스크립트를 썼습니다. 그러나 나는 당신이 파이썬에 얼마나 능숙한 지 잘 모르겠습니다 (모두 정통한 경우).이 스크립트를 최대한 사용하는 방법을 설명하려고 노력할 것입니다. 필요에 따라 많은 질문을하십시오.

import os,sys,shutil
### copies a list of files from source. handles duplicates.
def rename(file_name, dst, num=1):
    #splits file name to add number distinction
    (file_prefix, exstension) = os.path.splitext(file_name)
    renamed = "%s(%d)%s" % (file_prefix,num,exstension)

    #checks if renamed file exists. Renames file if it does exist.
    if os.path.exists(dst + renamed):
        return rename(file_name, dst, num + 1)
    else:
        return renamed

def copy_files(src,dst,file_list):
    for files in file_list:
        src_file_path = src + files
        dst_file_path = dst + files
        if os.path.exists(dst_file_path):
            new_file_name =  rename(files, dst)
            dst_file_path = dst + new_file_name

        print "Copying: " + dst_file_path
        try:
            shutil.copyfile(src_file_path,dst_file_path)
        except IOError:
            print src_file_path + " does not exist"
            raw_input("Please, press enter to continue.")

def read_file(file_name):
    f = open(file_name)
    #reads each line of file (f), strips out extra whitespace and 
    #returns list with each line of the file being an element of the list
    content = [x.strip() for x in f.readlines()]
    f.close()
    return content

src = sys.argv[1]
dst = sys.argv[2]
file_with_list = sys.argv[3]

copy_files(src,dst,read_file(file_with_list))

이 스크립트는 비교적 사용하기 쉬워야합니다. 먼저 위의 코드를 프로그램 gedit (우분투에 사전 설치되어 있어야 함) 또는 다른 텍스트 편집기에 복사하십시오.

완료된 후 파일을 홈 디렉토리에 move.py 로 저장하십시오 (디렉토리 일 수 있지만 쉽게 설명 할 수 있도록 홈 디렉토리를 사용하십시오). 파일이 포함 된 디렉토리를 PATH에 추가하십시오. 그런 다음 cd터미널에서 홈 디렉토리 (또는 move.py를 저장 한 디렉토리)로 이동하여 다음 명령을 입력하십시오.

python move.py /path/to/src/ /path/to/dst/ file.txt

이렇게하면 pic (1) .jpg, pic (2) .jpg 등의 형식으로 복제본을 사용하여 소스 디렉토리에서 대상 디렉토리로 나열된 모든 파일을 복사해야합니다. file.txt 는 각 항목과 함께 별도의 줄에 복사하려는 모든 그림을 나열하는 파일이어야합니다.

이 스크립트가 소스 디렉토리에 영향을 미치지 않아야하지만, 소스 및 대상 디렉토리에 대한 올바른 경로를 입력하십시오. 최악의 경우 파일을 잘못된 디렉토리에 복사하면 발생할 수 있습니다.

노트

  • 이 스크립트는 모든 원본 그림이 동일한 디렉토리에 있다고 가정합니다. 하위 디렉토리도 확인하려면 스크립트를 수정해야합니다.
  • 실수로 파일 이름을 잘못 입력하면, 스크립트는
    "파일이 존재하지 않습니다" 라는 오류를 뱉어 내고 계속하려면 "엔터를 누르십시오"라는 메시지를 표시하고 스크립트는 나머지 목록을 계속 복사합니다.
  • /소스
    디렉토리의 경로와 대상 디렉토리 의 경로를 모두 뒤 따르는 것을 잊지 마십시오 . 그렇지 않으면 스크립트에서 오류가 발생합니다.

고맙지 만 내 문제의 대부분을 해결했지만 일부 파일이 목록에 두 번 이상 나타납니다.이 복제본을 자동으로 이름을 바꾸려면 어떻게해야합니까? (예, 내가 뭘하는지에 대한 중복이 필요합니다.)
누군가를 PICT 너무 많은으로

다른 하위 폴더의 복제본이거나 file.jpg 및 file (1) .jpg와 같은 레이블이 붙어 있습니까? 그렇지 않으면 동일한 파일이 어떻게 있는지 잘 모르겠습니다. 귀하의 질문에 다소 대답하기 위해, 당신이 자동으로 사본의 이름을 자동으로 바꿀 간단한 라이너를 찾을 수 있다고 생각하지 않습니다. bash 또는 다른 유형의 스크립트를 작성해야 해당 유형의 기능을 얻을 수 있습니다. 그러나, 나는 아주 우스운 한 줄 명령을 보았으므로 일부 Linux 마법사가 나타나서 대답을 제공 할 수 있습니다.
Bryan

원래 각 파일 중 하나만 가지고 있지만 파일 이름은 목록에 두 번 이상 있습니다. 새 폴더에 파일을 배치하려고 할 때, 그리고 그 이름의 파일이 이미 존재하는 경우, 내가해야 할 일이 다소간에 파일 이름 끝에 (2) 정도를 추가해야합니다. 배치하십시오.
PICT 너무 많이 가진 사람

복사 할 파일 목록에 공백이없는 부분을 강조하고 싶습니다. {foo, bar, ..} 파일 사이에 공백이 있으면 명령이 작동하지 않습니다.
franksands

추가 바로 가기를 원하는 경우 명령 대체를 사용하여 파일의 절대 경로 즉, cp $(pwd)/{file1,file2} /path/to/dst/또는 cp $(pwd)/{file1,file2} $(pwd)/{renamed1,renamed2}등을
나타낼 수 있습니다

49

아마도 귀하의 질문에 대한 세부 정보가 누락되었지만 주어진 답변이 과도하게 보입니다. 스크립트가 아닌 명령 줄 솔루션을 원한다면 왜 그렇지 않습니까?

cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...

이 방법으로 좋은 점은 파일 이름을 탭으로 완성 할 수 있다는 것입니다.


5
이것은 맥 OS 시에라에서 "잘못된 옵션 --t"반환
geoyws

큰 대답, 훨씬 간단합니다. @geoyws 아마도 애플 버전에없는 POSIX 나 GNU 일 것이다. MSYS2가있는 데비안 리눅스 또는 Windows에서 잘 작동합니다.
underscore_d

좋은 제안! 아치 리눅스에서 일했습니다.
Edu Ruiz

brew install coreutils그런 다음 g접두사로 일반적인 gnu 물건을 얻을 수 있습니다 . 그래서 그것은gcp -t ....
T.Chmelevskij

Mac OS는 BSD 버전의을 사용 cp하며, 특히 OpenBSDFreeBSD 모두 해당 옵션을 사용할 수 없습니다. 예, 이것은 GNU cp 전용입니다. 또한 POSIX 표준에 의해 지정되지 않았습니다 . 이 우분투 특정 사이트이기 때문에,이 허용되지만 운영 체제의 사이에 스크립트를 포팅하는 것이 POSIX 표준에 충실하는 것이 좋습니다
세르지 Kolodyazhnyy

7

다음은 순수한 bash 솔루션입니다. 입력 파일 (한 줄에 하나씩)에서 파일 이름을 읽고 각 파일을 복사하여 중복 이름을 바꿉니다.

#!/usr/bin/env bash

## The destination folder where your files will
## be copied to.
dest="bar";

## For each file path in your input file
while read path; do 
    ## $target is the name of the file, removing the path. 
    ## For example, given /foo/bar.txt, the $target will be bar.txt.
    target=$(basename "$path"); 
    ## Counter for duplicate files
    c=""; 
    ## Since $c is empty, this will check if the
    ## file exists in target.
    while [[ -e "$dest"/"$target"$c ]]; do
        echo "$target exists"; 
        ## If the target exists, add 1 to the value of $c
        ## and check if a file called $target$c (for example, bar.txt1)
        ## exists. This loop will continue until $c has a value
        ## such that there is no file called $target$c in the directory.
        let c++; 
        target="$target"$c; 
    done; 
    ## We now have everything we need, so lets copy.
    cp "$path" "$dest"/"$target"; 
done

이 스크립트를 사용자의 폴더에 저장 $PATH하고 경로 목록을 입력으로 호출하십시오.

auto_copy.sh < file_paths.txt

터미널에서 명령으로 전체를 실행할 수도 있습니다.

while read path; do 
   target=$(basename "$path"); 
   c=""; 
   while [[ -e bar/"$target"$c ]]; do 
    echo "$target exists"; 
    let c++; 
    target="$target"$c; 
   done; 
   cp "$file" bar/"$target"; 
done < file_names;

1

질문에 대한 설명에 따르면, 내 이해는 다음과 같습니다.

  • 파일 목록, 아마도 텍스트 파일이 있습니다 input.txt
  • 이 목록에는 파일 이름 만 포함됩니다
  • 이러한 파일 이름이있는 특정 디렉토리가 있습니다.

따라서 다음 명령을 사용할 수 있습니다.

xargs -I % --arg-file=input.txt cp  /path/to/origin_dir/%  /path/to/destination

설명:

  • -I % 명령 내에서 사용될 현재 처리 된 파일의 기호를 지정합니다.
  • --arg-file=input.txt 명령에서 인수를 받도록 지정 input.txt
  • cp /path/to/origin_dir/% /path/to/destination/현재 처리 된 파일 로 대체 되고 이름 이 지정된 cp명령을 수행 합니다./path/to/origin_dir/%/path/to/origin_dir/

실제 예 :

$ cat input.txt
file2.txt
file1.txt
file3.txt
$ ls ./docs
file1.txt  file2.txt  file3.txt
$ xargs -I % --arg-file=input.txt cp ./docs/% ./docs_destination/
$ ls ./docs_destination/
file1.txt  file2.txt  file3.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.