我有一个很大的图片文件夹(数千张),并且我有一长串文件(按确切文件名列出),我需要将它们复制到另一个文件夹。我想知道是否有办法从这个文件夹中按名称选择几个特定文件,然后使用终端将它们复制到另一个文件夹,而无需逐个复制它们?
答案1
只需从命令行一次复制多个文件即可
有多种方法可以实现此目的。我见过的最简单的方法是使用以下方法。
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 将被复制。
从你提出问题的方式来看,我相信这就是你要找的东西,但听起来你可能在寻找一个命令来读取文件列表并将它们全部复制到某个目录。如果是这样的话,请告诉我,我会修改我的答案。
使用 python 处理重复项
所以我写了一个小的 Python 脚本,我相信它应该能完成这项工作。但是,我不确定您对 Python 的了解程度(如果了解的话),所以我将尽我所能解释如何使用这个脚本,请根据需要提出尽可能多的问题。
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 程序(Ubuntu 应该已预装)或任何其他文本编辑器中。
完成后,将文件另存为移动.py在您的主目录中(可以是任何目录,但为了便于说明,我们仅使用主目录)或将文件所在的目录添加到您的 PATH。然后cd
从终端进入您的主目录(或您保存 move.py 的任何目录)并输入以下命令:
python move.py /path/to/src/ /path/to/dst/ file.txt
这应该将源目录中列出的所有文件复制到目标目录,其中重复文件采用 pic(1).jpg、pic(2).jpg 等格式。 文件.txt应该是一个列出您想要复制的所有图片的文件,每个条目占一行。
该脚本绝不会影响源目录,但是只要确保输入源目录和目标目录的正确路径即可,最糟糕的情况就是将文件复制到错误的目录。
笔记
- 此脚本假定所有原始图片都位于同一目录中。如果您希望它也检查子目录,则需要修改脚本。
- 如果您不小心输入了错误的文件名,脚本将抛出错误
“文件不存在”并提示您“按回车键”继续,然后脚本将继续复制列表的其余部分。 - 不要忘记
/
源目录路径
和目标目录路径的末尾。否则脚本会向您返回错误。
答案2
也许我遗漏了你问题的细节,但给出的答案似乎太多了。如果你想要一个命令行解决方案而不是脚本,为什么不呢:
cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...
这样做的好处是你可以通过制表符完成文件名
答案3
这是一个纯 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;
答案4
来自 cp --help:
cp [OPTION]... SOURCE... DIRECTORY
三个SOURCE...
逗号表示多个参数,即你可以
cd your_source_dir
cp file1 file2 dest_dir