繁体   English   中英

如何根据包含文件夹名称的文件将文件复制到文件夹中?

[英]How do I copy files into folders based on the file containing the folder name?

的Python版本:2.7.13

操作系统:Windows

因此,我正在编写一个脚本,根据要求将各种名称的文件复制到一个特定的文件夹中,该要求是文件中必须包含文件夹名称。 (我对此很陌生,只是尝试创建脚本以提高工作效率-我查看了很多StackOverflow页面和网络上的某些地方,但找不到用于此特定任务的与Python相关的东西)

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

本质上是“如果有的话(目录名中的x在列表中为x):”,“将文件移动到x”。

关于so​​urceFolder和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:经过一些调整和外部帮助之后,就工作代码而言,这就是我最终的目的(为了让遇到此问题的任何人受益)。 一些变量更改了名称,但希望该结构可读。

从os导入shutil,os,re,stat从os.path导入listdir导入isfile,join

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

这就是我做比较的方式:

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

这样可以解决问题吗?

我试图使它尽可能接近您的原始代码。 我们将其中包含文件夹名称的所有文件丢到相应的文件夹中。 我们不会使用设置的缓存遍历所有目录重复任何文件。

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

您的解决方案使用any()确定文件是否与任何子目录匹配,然后将文件移至存储在subdir的最后一个值。 并注意subdirName在上一个循环中的最后设置方式,因此其值在第二个循环中将永远不变。 我也看到了其他一些问题。 您需要一个子目录名称列表,但是还需要一个完整的相对路径列表,假设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)

我没有测试上面的内容,但是应该可以使您了解如何进行此工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM