【问题标题】:How do I copy files into folders based on the file containing the folder name?如何根据包含文件夹名称的文件将文件复制到文件夹中?
【发布时间】:2019-03-28 03:38:12
【问题描述】:

Python 版本:2.7.13

操作系统:Windows

所以我正在编写一个脚本,根据文件名中包含文件夹名称的要求,将各种名称的文件复制到特定文件夹中。 (我对此相当陌生,只是试图创建脚本以提高工作效率 - 我查看了大量 StackOverflow 页面和网络上的一些地方,但找不到与 Python 相关的内容)

我已将文件夹转换为可以搜索文件名的字符串列表,但是当我将它们复制过来时,它们都会进入找到的第一个文件夹。我需要帮助的确切部分是如何将文件复制到找到字符串匹配的文件夹中。

本质上,“如果有的话(目录中的 x 对应于列表中的 x):”、“将文件移动到 x”。

关于 sourceFolder 和 destFolder,这些是从代码前面的用户输入中获取的变量。 (sourceFolder 包含文件,destFolder 包含我要复制到的子文件夹)

编辑:我在 destFolder 中有多个子文件夹,如果它们与字符串匹配,我可以复制要复制的文件(如果不存在匹配项,则不会复制)。但是,当它们复制时,它们都会转到同一个子文件夹。

list=[]

if var == "y": #Checks for 'Yes' answer
    for subdir, dirs, files in os.walk(destFolder):
        subdirName = subdir[len(destFolder) + 1:] #Pulls subfolder names as strings
        print subdirName
        list.insert(0, subdirName)
        print "Added to list"


for subdir, dirs, files in os.walk(sourceFolder):
        for file in files:
            dirName = os.path.splitext(file)[0] #This is the filename without the path
            destination = "{0}\{1}".format(destFolder, subdirName)

            string = dirName #this is the string we're looking in
            if any(x in dirName for x in list):
                print "Found string: " + dirName
                shutil.copy2(os.path.join(subdir, file), destination)
            else:
                print "No String found in: " + dirName

编辑 2: 经过一些调整和外部帮助,这就是我最终得到的工作代码(为了任何遇到这个问题的人)。一些变量更改了名称,但希望结构是可读的。

进口shutil,操作系统,重新,统计 从操作系统导入列表目录 from os.path 导入isfile,加入

destKey = dict()

if var == "y": #Checks for 'Yes' answer
    for root, dirs, files in os.walk(destFolder):
        for dest_folder in dirs: #This is the folder, for each we look at
            destKey[dest_folder] = os.path.join(root, dest_folder) #This is where we convert it to a dictionary with a key

for sourceFile in os.listdir(sourceFolder):
    print ('Source File: {0}').format(sourceFile)
    sourceFileName = os.path.basename(sourceFile) #filename, no path
    for dest_folder_name in destKey.keys():
        if dest_folder_name in sourceFileName.split('-'): #checks for dest name in sourceFile
            destination = destKey[dest_folder_name]
            print "Key match found for" + dest_folder_name
            shutil.copy2(os.path.join(sourceFolder, sourceFile), destination)
            print "Item copied: " + sourceFile

【问题讨论】:

    标签: python


    【解决方案1】:

    这就是我将如何进行比较:

    list = ["abc", "def", "ghi"]
    
    dirname = "abcd"
    for x in list:
        if x in dirname:
            print(dirname, x)
    

    所以你的代码应该是这样的:

    for subdir, dirs, files in os.walk(sourceFolder):
        for file in files:
            dirName = os.path.splitext(file)[0] #This is the filename without the path
            destination = "{0}\{1}".format(destFolder, subdirName)
    
            for x in list:
                if x in dirName:
                    print "Found string: " + dirName
                    shutil.copy2(os.path.join(subdir, file), destination)
                else:
                    print "No String found in: " + dirName
    

    这能解决问题吗?

    【讨论】:

      【解决方案2】:

      我试图让它尽可能接近您的原始代码。我们将任何具有文件夹名称的文件放入相应的文件夹中。我们不会使用一组缓存在遍历所有目录时重复任何文件。

      import os, shutil
      
      dirs_ls = []
      
      destFolder = 'Testing'
      for subdir, dirs, files in os.walk(destFolder):
          subdirName = subdir[len(destFolder) + 1:]  # Pulls subfolder names as strings
          dirs_ls.append(subdirName)
      
      dirs_ls = filter(None, dirs_ls)
      
      copied_files = set()
      for subdir, dirs, files in os.walk(destFolder):
          for file_name in files:
              if file_name in copied_files:
                  continue
      
              file_name_raw = file_name.split('.')[0]
      
              for dir in dirs_ls:
                  if dir not in file_name_raw:
                      continue
                  shutil.copy2(os.path.join(destFolder, file_name), os.path.join(destFolder, file_name_raw))
                  copied_files.add(file_name)
      

      脚本运行前的目录结构:

      .
      ├── bro
      ├── bro.txt
      ├── foo
      ├── foo.txt
      ├── yo
      └── yo.txt
      

      脚本运行后的目录结构:

      .
      ├── bro
      │   └── bro.txt
      ├── bro.txt
      ├── foo
      │   └── foo.txt
      ├── foo.txt
      ├── yo
      │   └── yo.txt
      └── yo.txt
      

      【讨论】:

        【解决方案3】:

        您的解决方案是使用 any() 来确定文件是否与任何子目录匹配,然后将文件移动到存储在 subdir 中的最后一个值。并注意 subdirName 是如何在 previous 循环中最后设置的,因此它的值在第二个循环中永远不会改变。我也看到了其他一些问题。您需要一个子目录名称列表,但您还需要一个完整相对路径的列表,假设 destFolder 和 sourceFolder 不相同并且具有子目录。最好不要用您自己的变量名覆盖list 等基本类型。试试这个:

        from os.path import dirname, join, splitext
        from os import walk
        
        dir_list = []
        if var == "y": #Checks for 'Yes' answer
            for subdir, dirs, files in walk(destFolder):
                dir_list.append(subdir)  # keeping the full path, not just the last directory
                print 'Added "{0}" to the list'.format(subdir)
        
        for subdir, dirs, files in walk(sourceFolder):
            for file in files:
                fname = splitext(file)[0]  # This is the filename without the path
                for dpath in dir_list:
                    # Fetch last directory in the path
                    dname = dirname(dpath)
                    if dname in fname:
                        # Directory name was found in the file name; copy the file
                        destination = join(destFolder, dpath, file)
                        shutil.copy2(join(subdir, file), destination)
        

        我还没有测试过上述内容,但这应该让您了解如何进行这项工作。

        【讨论】:

        • 嘿!所以这有很大帮助,但是我仍然有一些问题(主要是由于我缺乏完全掌握语言)。我的一个朋友最终回复了我,经过一些调整,我们最终得到了我放在“编辑 2”下的内容 - 它具有类似的结构,但使用字典而不是列表。
        猜你喜欢
        • 1970-01-01
        • 2016-12-23
        • 1970-01-01
        • 1970-01-01
        • 2019-11-27
        • 2021-05-15
        • 2011-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多