在python中移动文件并创建目录(如果文件类型是特定的)
这可能是一个简单的问题,但我对python和一般编程是全新的 我正在开发一个简单的程序,将.mp3文件从一个位置复制/移动到另一个位置,同时镜像源位置的目录结构。到目前为止,我所做的一切都是有效的,但是它也会在目标位置创建新的文件夹,即使源文件夹不包含mp3文件。我只想在源包含.mp3时创建新目录,否则可能会导致目标中出现一堆空文件夹 以下是我到目前为止的情况:在python中移动文件并创建目录(如果文件类型是特定的),python,os.walk,Python,Os.walk,这可能是一个简单的问题,但我对python和一般编程是全新的 我正在开发一个简单的程序,将.mp3文件从一个位置复制/移动到另一个位置,同时镜像源位置的目录结构。到目前为止,我所做的一切都是有效的,但是它也会在目标位置创建新的文件夹,即使源文件夹不包含mp3文件。我只想在源包含.mp3时创建新目录,否则可能会导致目标中出现一堆空文件夹 以下是我到目前为止的情况: import os import shutil #Used for copying files ##CONFIG source_di
import os
import shutil #Used for copying files
##CONFIG
source_dir = "C:\Users\username\Desktop\iTunes\\" #set the root folder that you want to scan and move files from. This script will scan recursively.
destPath = "C:\Users\username\Desktop\converted From iTunes" #set the destination root that you want to move files to. Any non-existing sub directories will be created.
ext = ".mp3" #set the type of file you want to search for.
count = 0 #initialize counter variable to count number of files moved
##
##FIND FILES
for dirName, subdirList, fileList in os.walk(source_dir):
#set the path for the destination folder(s)
dest = destPath + dirName.replace(source_dir, '\\')
#if the source directory doesn't exist in the destination folder
#then create a new folder
if not os.path.isdir(dest):
os.mkdir(dest)
print('Directory created at: ' + dest)
for fname in fileList:
if fname.endswith(ext) :
#determine source & new file locations
oldLoc = dirName + '\\' + fname
newLoc = dest + '\\' + fname
if os.path.isfile(newLoc): # check to see if the file already exists. If it does print out a message saying so.
print ('file "' + newLoc + fname + '" already exists')
if not os.path.isfile(newLoc): #if the file doesnt exist then copy it and print out confirmation that is was copied/moved
try:
shutil.move(oldLoc, newLoc)
print('File ' + fname + ' copied.')
count = count + 1
except IOError:
print('There was an error copying the file: "' + fname + '"')
print 'error'
print "\n"
print str(count) + " files were moved."
print "\n"
因此,如果文件夹结构类似于:
root->
band 1->
album name->
song.m4a,
song2.m4a
现在,它将在目标驱动器中创建所有这些文件夹,即使没有.mp3可复制
感谢您的帮助 不会用更少的行完成您想要的任务吗?我想我会为这类事情创建自己的包装副本:
def fcopy(src,dest):
"""
Copy file from source to dest. dest can include an absolute or relative path
If the path doesn't exist, it gets created
"""
dest_dir = os.path.dirname(dest)
try:
os.makedirs(dest_dir)
except os.error as e:
pass #Assume it exists. This could fail if you don't have permissions, etc...
shutil.copy(src,dest)
现在,您可以在任何
.mp3
文件上调用此函数来遍历树。对于您现有的代码,我能想到的最简单的方法就是让它跳过任何没有.mp3文件的文件夹。这可以通过在循环的顶部添加以下项和if
语句来轻松完成。和函数可以一起使用,以简化对具有适当扩展名的文件的检查
from itertools import ifilter
from fnmatch import fnmatch
ext = '.mp3'
fnPattern = '*'+ext
for dirName, subdirList, fileList in os.walk(source_dir):
if not any(ifilter(lambda fname: fnmatch(fname, fnPattern), fileList)):
print ' skipping "{}"'.format(dirName)
continue
...
您还必须将代码中的os.mkdir(dest)
更改为os.makedirs(dest)
,以确保在需要将文件复制到目标目录的相应子分支时,创建早期迭代跳过的任何子目录
您可以通过创建并保存具有扩展名的匹配文件的可能为空的迭代器,然后稍后再次使用该迭代器来确定要复制的文件,从而稍微优化一些内容:
from itertools import ifilter
from fnmatch import fnmatch
ext = '.mp3'
fnPattern = '*'+ext
for dirName, subdirList, fileList in os.walk(source_dir):
# generate list of files in directory with desired extension
matches = ifilter(lambda fname: fnmatch(fname, fnPattern), fileList)
# skip subdirectory if it does not contain any files of interest
if not matches:
continue
...
... create destination directory with os.makedirs()
...
# copy each file to destination directory
for fname in matches:
... copy file
使用
ignore=…
关键字在这里看起来很优雅,但不能以一堆空目录结束?据我所知,shutils.copytree会复制整个文件夹结构。我只想复制一个文件夹,如果它包含.mp3文件。我会花一些时间来阅读这一点,了解它是如何工作的。看起来很有希望。正如我所说,我对编程非常陌生,大多数概念对我来说都是新的。谢谢。但是你怎么知道它没有任何包含.mp3
的子目录呢?我试图修改我的代码,让它在创建目录之前查找mp3,但是如果有一个文件夹本身不包含mp3,但包含一个包含mp3的子文件夹,那么这将失败。这看起来像是跳过一个文件夹(及其子文件夹?),如果它不包含MP3?@mgilson:os.walk
生成树中以目录source\u dir
为根的每个目录(包括source\u dir
本身),而不管是否对中的每个目录进行了任何处理。这意味着即使目录本身被if/continue
@martineau跳过,树中目录的子目录也会被处理——是的,我明白了。问题是当你要将一个文件复制到一个不存在的目标目录时。@mgilson:处理这个问题的一个简单方法是在将任何文件复制到每个目标目录之前将os.makedirs()
应用到每个目标目录中,这当然需要在OP的代码中做更多的修改。