问题描述
我有一个很大的图片文件夹(数千),并且我有一长串文件,按照确切的文件名,我需要复制到另一个文件夹。我想知道是否有方法可以按名称从该文件夹中选择几个特定文件,并使用终端将它们复制到另一个文件夹,而不单独复制它们?
最佳解决方案
只需从命令行一次复制多个文件
有几种方法可以实现这一点。我见过的最简单的方法是使用以下内容。
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中应该是pre-installed)或任何其他文本编辑器。
完成后,将文件保存为主目录中的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应该是一个文件,它列出了您想要在每个条目上单独复制的所有照片。
这个脚本决不应该影响源目录,但只要确保输入源和目标目录的正确路径,并且可能发生的最坏情况是将文件复制到错误的目录。
笔记
-
该脚本假定所有原始图片都在同一个目录中。如果你想要检查子目录,那么脚本将需要修改。
-
如果意外错误输入了一个文件名,脚本将吐出错误“文件不存在”并提示您”press enter”继续,脚本将继续复制列表的其余部分。
-
不要忘记源目录路径和目标目录路径的尾部
/
。否则,脚本会向你吐出一个错误。
希望这可以帮助!
次佳解决方案
也许我错过了你的问题的细节,但给出的答案似乎过度。如果你想要一个命令行解决方案而不是脚本,为什么不:
cd /path/to/src/
cp -t /path/to/dst/ file1 file2 file3 ...
这样做的好处是您可以选项卡填写文件名
第三种解决方案
这是一个纯粹的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;