[英]How do I copy files into folders based on the file containing the folder name?
Python Version: 2.7.13 的Python版本:2.7.13
OS: Windows 操作系统:Windows
So I'm writing a script to copy files of various names into a specific folder based on the requirement that they contain the folder name inside the file name. 因此,我正在编写一个脚本,根据要求将各种名称的文件复制到一个特定的文件夹中,该要求是文件中必须包含文件夹名称。 (I'm fairly new to this, just trying to create scripts for more efficiency at my job - I looked at a ton of StackOverflow pages and some places around the web but couldn't find something relating to Python for this specific task)
(我对此很陌生,只是尝试创建脚本以提高工作效率-我查看了很多StackOverflow页面和网络上的某些地方,但找不到用于此特定任务的与Python相关的东西)
I've converted the folders into a list of strings I can search the filenames for, however when I go to copy them over they all go into the first folder found. 我已经将文件夹转换成可以搜索文件名的字符串列表,但是当我将它们复制过来时,它们全部进入找到的第一个文件夹。 The exact piece of this I need help with is how to get the file to copy into the folder it found a string match for.
我需要帮助的确切部分是如何将文件复制到找到匹配字符串的文件夹中。
Essentially, "if any(x in dirName for x in list):", "move file to x". 本质上是“如果有的话(目录名中的x在列表中为x):”,“将文件移动到x”。
Regarding sourceFolder and destFolder, these are variables gotten from user input earlier in the code. 关于sourceFolder和destFolder,这些是从代码前面的用户输入获得的变量。 (sourceFolder contains the files, destFolder contains the subfolders I'm copying to)
(sourceFolder包含文件,destFolder包含我要复制到的子文件夹)
EDIT: I have multiple subfolders in the destFolder, I can get the files to copy if they match a string, (if no match is present, they don't copy). 编辑:我在destFolder中有多个子文件夹,如果它们与字符串匹配,我可以获取要复制的文件(如果不存在匹配项,则不进行复制)。 However, when they do copy, they all go to the same subfolder.
但是,当它们确实进行复制时,它们都进入同一个子文件夹。
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
EDIT 2: After some tweaking and outside help, here's what I ended up with as far as working code goes (For the sake of anyone who comes across this). 编辑2:经过一些调整和外部帮助之后,就工作代码而言,这就是我最终的目的(为了让遇到此问题的任何人受益)。 Some of the variables changed names, but hopefully the structure is readable.
一些变量更改了名称,但希望该结构可读。
import shutil, os, re, stat from os import listdir from os.path import isfile, join 从os导入shutil,os,re,stat从os.path导入listdir导入isfile,join
destKey = dict() 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
This is how I would do the comparison: 这就是我做比较的方式:
list = ["abc", "def", "ghi"]
dirname = "abcd"
for x in list:
if x in dirname:
print(dirname, x)
So your code would look like this: 因此,您的代码如下所示:
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
Does that solve the problem? 这样可以解决问题吗?
I tried to keep it as close to your original code as possible. 我试图使它尽可能接近您的原始代码。 We throw any files that have the folder name in them into the corresponding folder.
我们将其中包含文件夹名称的所有文件丢到相应的文件夹中。 We don't repeat any files through our walk of all dirs using a set cache.
我们不会使用设置的缓存遍历所有目录重复任何文件。
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)
Directory structure prior to script run: 脚本运行之前的目录结构:
.
├── bro
├── bro.txt
├── foo
├── foo.txt
├── yo
└── yo.txt
Directory structure after script run: 脚本运行后的目录结构:
.
├── bro
│ └── bro.txt
├── bro.txt
├── foo
│ └── foo.txt
├── foo.txt
├── yo
│ └── yo.txt
└── yo.txt
Your solution is using any() to determine if the file matches to any of the subdirectories, and then it moves the file to the last value stored in subdir
. 您的解决方案使用any()确定文件是否与任何子目录匹配,然后将文件移至存储在
subdir
的最后一个值。 And note how subdirName is last set in the previous loop, so its value will never change in the second loop. 并注意subdirName在上一个循环中的最后设置方式,因此其值在第二个循环中将永远不变。 I'm seeing a few other issues as well.
我也看到了其他一些问题。 You need a list of subdirectory names but then you also need a list of complete relative paths, assuming destFolder and sourceFolder aren't the same and have subdirectories.
您需要一个子目录名称列表,但是还需要一个完整的相对路径列表,假设destFolder和sourceFolder不相同,并且具有子目录。 It's also best to not overwrite basic types like
list
with your own variable name. 最好不要用您自己的变量名覆盖诸如
list
类的基本类型。 Try this: 尝试这个:
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)
I haven't tested the above, but that should give you an idea of how to make this work. 我没有测试上面的内容,但是应该可以使您了解如何进行此工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.