사진 (수천 개)의 큰 폴더가 있으며 정확한 파일 이름으로 다른 폴더로 복사해야하는 긴 파일 목록이 있습니다. 이름 으로이 폴더에서 여러 특정 파일을 선택하고 터미널을 사용하여 개별 폴더로 복사하지 않고 다른 폴더로 복사 할 수있는 방법이 있는지 알고 싶습니다.
사진 (수천 개)의 큰 폴더가 있으며 정확한 파일 이름으로 다른 폴더로 복사해야하는 긴 파일 목록이 있습니다. 이름 으로이 폴더에서 여러 특정 파일을 선택하고 터미널을 사용하여 개별 폴더로 복사하지 않고 다른 폴더로 복사 할 수있는 방법이 있는지 알고 싶습니다.
답변:
이를 달성 할 수있는 몇 가지 방법이 있습니다. 내가 본 가장 쉬운 것은 다음을 사용하는 것입니다.
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 는 각 항목과 함께 별도의 줄에 복사하려는 모든 그림을 나열하는 파일이어야합니다.
이 스크립트가 소스 디렉토리에 영향을 미치지 않아야하지만, 소스 및 대상 디렉토리에 대한 올바른 경로를 입력하십시오. 최악의 경우 파일을 잘못된 디렉토리에 복사하면 발생할 수 있습니다.
/
소스 cp $(pwd)/{file1,file2} /path/to/dst/
또는 cp $(pwd)/{file1,file2} $(pwd)/{renamed1,renamed2}
등을
아마도 귀하의 질문에 대한 세부 정보가 누락되었지만 주어진 답변이 과도하게 보입니다. 스크립트가 아닌 명령 줄 솔루션을 원한다면 왜 그렇지 않습니까?
cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...
이 방법으로 좋은 점은 파일 이름을 탭으로 완성 할 수 있다는 것입니다.
brew install coreutils
그런 다음 g
접두사로 일반적인 gnu 물건을 얻을 수 있습니다 . 그래서 그것은gcp -t ....
cp
하며, 특히 OpenBSD 나 FreeBSD 모두 해당 옵션을 사용할 수 없습니다. 예, 이것은 GNU cp
전용입니다. 또한 POSIX 표준에 의해 지정되지 않았습니다 . 이 우분투 특정 사이트이기 때문에,이 허용되지만 운영 체제의 사이에 스크립트를 포팅하는 것이 POSIX 표준에 충실하는 것이 좋습니다
다음은 순수한 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;
질문에 대한 설명에 따르면, 내 이해는 다음과 같습니다.
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
cp -rp /copying/from/{folder1/,folder2/,folder3/} path/to/folder
, 여기서p
폴더 권한을 복사합니다.