将多个特定文件从一个文件夹复制到另一个文件夹

我有一个大的图片文件夹(数千),我有一个很长的文件列表,按照确切的文件名,我需要复制到另一个文件夹。 我想知道是否有一种方法可以通过名称从该文件夹中选择几个特定文件,并使用终端将它们复制到另一个文件夹,而无需单独复制它们?

只需从命令行一次复制多个文件即可

有几种方法可以实现这一目标。 我见过的最简单的方法是使用以下内容。

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中)或任何其他文本编辑器中。

完成后,将文件作为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应该是一个文件,列出您要在每个条目单独行上复制的所有图片。

此脚本决不会影响源目录,但只需确保输入到源和目标目录的正确路径,并且可能发生的最坏情况是将文件复制到错误的目录。

笔记

  • 此脚本假定所有原始图片都在同一目录中。 如果您想要检查子目录,则需要修改脚本。
  • 如果您不小心输错了文件名,脚本将吐出错误
    “文件不存在”并提示您“按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; 

根据问题的描述,我的理解是:

  • 有一个文件列表,大概是一个文本文件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