【问题标题】:Copy files from one folder to another with matching names in .txt file将文件从一个文件夹复制到另一个在 .txt 文件中具有匹配名称的文件夹
【发布时间】:2019-07-25 12:37:12
【问题描述】:

我想根据.txt 文件中的匹配文件名将文件从一个大文件夹复制到另一个文件夹。

我的list.txt 文件包含文件名:

S001
S002
S003

另一个大文件夹包含许多 ex 文件。 S001, S002, S003, S004, S005.

我只想从这个大文件夹中复制与我的list.txt 文件中的文件名匹配的文件。

我尝试过 Bash、Python - 不工作。

for /f %%f in list.txt do robocopy SourceFolder/ DestinationFolder/ %%f

也不工作。

我在 Python 中的逻辑不起作用:

import os
import shutil

def main():

    destination = "DestinationFolder/copy"

    source = "SourceFolder/MyBigData"

    with open(source, "r") as lines:
        filenames_to_copy = set(line.rstrip() for line in lines)

    for filenames in os.walk(destination):
        for filename in filenames:
            if filename in filenames_to_copy:
                shutil.copy(source, destination)

在 Bash、Python 或 R 中有任何答案吗?

谢谢

【问题讨论】:

  • 您能具体解释一下 Python 尝试的哪一部分不起作用吗?
  • 你想复制到哪里?在另一个文件夹中?
  • 是的,我想将匹配的文件名复制到另一个文件夹中。

标签: python r shell


【解决方案1】:

我认为您的 Python 代码的问题在于,对于 os.walk(),您的 filename 每次都会是一个列表,而不会在您的 filenames_to_copy 中找到。

我建议尝试使用os.listdir(),因为这会以字符串形式返回文件名/文件夹名称列表 - 更容易与您的 filenames_to_copy 进行比较。

其他注意事项 - 也许您想在源而不是目标上执行 os.listdir()(或 os.walk())。目前,如果文件已存在于目标中,您只会将文件从源复制到目标。

【讨论】:

  • 是的,我已经在源代码上尝试过 os.walk(对上面的错误感到抱歉),但它仍然无法正常工作.. 即使使用 os.listdir()
  • 感谢@JezMonkey 的帮助!我的脚本现在可以运行了!
【解决方案2】:

os.walk() 将返回一个包含三个元素的元组:检查的当前目录的名称、其中的文件夹列表以及其中的文件列表。你只对后者感兴趣。所以你应该迭代:

for _, _, filenames in os.walk(destination):

正如 JezMonkey 所指出的,os.listdir() 更易于使用,因为它会列出所请求目录中的文件和文件夹。但是,您将失去 os.walk() 启用的递归搜索。如果您所有的文件都在同一个文件夹中并且没有隐藏在某些文件夹中,您宁愿使用os.listdir()

我在您的代码中看到的第二个问题是,当我认为您想复制 os.path.join(source, filename) 时,您复制了 source

您能否发布您在 Python 脚本中遇到的确切错误,以便我们更好地帮助您。

更新

您实际上不需要列出源文件夹中的所有文件。使用os.path.exists,您可以检查文件是否存在,如果存在则复制它。

import os
import shutil

def main():
    destination = "DestinationFolder/copy"
    source = "SourceFolder/MyBigData"

    with open("list.txt", "r") as lines: # adapt the name of the file to open to your exact location.
        filenames_to_copy = set(line.rstrip() for line in lines)

    for filename in filenames_to_copy:
        source_path = os.path.join(source, filename)
        if os.path.exists(source_path):
            print("copying {} to {}".format(source_path, destination))
            shutil.copy(source_path, destination)

【讨论】:

  • 脚本没有显示任何错误但什么也不做!
  • 我认为这个问题应该可以通过 ubuntu 上的命令行轻松解决,但我无法弄清楚代码..
  • 您的所有源文件是在同一个文件夹中还是在不同的文件夹中?在第二种情况下,您是将它们全部复制到同一个文件夹中还是保留源架构?
  • @HKS 你可以在循环的各个部分添加一个打印语句来打印filename - 这会让你看到你正在循环的内容。
  • 在一个目录中 - 我有一个包含可能文件的大文件夹 - 但我不想要所有文件,我只想要与我在 list.txt 文件中的文件名匹配的文件。 list.txt 文件,包含所有文件的大文件夹,目标文件夹位于我在开始时提到的那个目录中..
【解决方案3】:

感谢@PySaad 和@Guillaume 的贡献,尽管我的脚本现在可以运行:我补充说:

             if os.path.exists(copy_to):
            shutil.rmtree(copy_to)
            shutil.copytree(file_to_copy, copy_to)

到脚本和它的工作就像一个魅力:)

非常感谢您的帮助!

【讨论】:

  • 虽然我真的很想听到更多关于 bash 脚本的信息。我认为应该有一个单行 bash 脚本来完成这项任务,就像我所做的那样,但它不工作,所以我也会处理它..
  • 您可以在 subprocess.call() 中尝试使用 robocopy(windows) 或 cp(linux),当您有大量文件时,它们可以快速安静地工作
  • 我试图为答案投票。但我无法查看我是否正确。
【解决方案4】:

你可以试试下面的代码 -

import glob

big_dir = "~\big_dir"
copy_to = "~\copy_to"
copy_ref = "~\copy_ref.txt"

big_dir_files = [os.path.basename(f) for f in glob.glob(os.path.join(big_dir, '*'))]
print 'big_dir', big_dir_files # Returns all filenames from big directory

with open(copy_ref, "r") as lines:
    filenames_to_copy = set(line.rstrip() for line in lines)
    print filenames_to_copy   # prints filename which you have in .txt file

    for file in filenames_to_copy:
        if file in big_dir_files:   # Matches filename from ref.txt with filename in big dir
            file_to_copy = os.path.join(big_dir, file)
            copy_(file_to_copy, copy_to)

def copy_(source_dir, dest_dir):
    files = glob.iglob(os.path.join(source_dir, '*'))
    for file in files:
        dest = os.path.join(dest_dir, os.path.basename(os.path.dirname(file)))
        if not os.path.exists(dir_name):
            os.mkdir(dest)
        shutil.copy2(file, dest)

参考:

https://docs.python.org/3/library/glob.html

【讨论】:

  • 这个脚本正在打印两个文件 - big_dir 中的所有文件名,以及 - copy_ref.txt 文件中的文件名。错误是:文件“copy.py”,第 18 行,在 shutil.copy(big_dir, copy_to) 文件“/home/heena/anaconda3/lib/python3.6/shutil.py”,第 245 行,在 copyfile(src, dst, follow_symlinks=follow_symlinks) 文件“/home/ heena/anaconda3/lib/python3.6/shutil.py",第 120 行,在副本文件中,open(src, 'rb') as fsrc:
  • IsADirectoryError: [Errno 21] 是目录:"~\big_dir"
  • 所以你得到了想要的文件,现在唯一的问题是复制。对吗?
  • IsADirectoryError: [Errno 21] 是目录:'/MyDir/All-samples/S011837
  • 我注意到了!仍然出现相同的错误:每次使用不同的文件名:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2020-07-30
相关资源
最近更新 更多