文件扩展名Python
如果一个目录同时包含“.m”和“.xml”两个文件,我希望脚本同时找到它们(目前不会这样做,而是转到“else”语句)。给定的参数应查找目录中的所有文件文件扩展名Python,python,Python,如果一个目录同时包含“.m”和“.xml”两个文件,我希望脚本同时找到它们(目前不会这样做,而是转到“else”语句)。给定的参数应查找目录中的所有文件 python script.py --dir C:\\path\\path\\*.* #This should take all files (doesn't matter what type ex 'm', 'xml' 'txt' etc.). 如果用户只需要xml文件,他会为“.m”文件编写*.xml,反之亦然。请注意,如果用户只需要“X
python script.py --dir C:\\path\\path\\*.* #This should take all files (doesn't matter what type ex 'm', 'xml' 'txt' etc.).
如果用户只需要xml文件,他会为“.m”文件编写*.xml,反之亦然。请注意,如果用户只需要“XML”或“m”文件,脚本将找到它
def main(argv):
args = argumentParser(argv)
if args.dirname.endswith('.m'):
overrideM(args)
elif args.dirname.endswith('.xml'):
xmlOverride(args)
elif args.dirname.endswith(('.m', '.xml')): #Can I do like this?
#Here I want to run both of my function.
overrideM()
xmlOverride()
else:
print "Error can't find files"
我的“m”函数(它的一小部分)
我的“XML”函数(它的一小部分)
1) 我与微软的Windows没有太多的友谊,但不管怎样,它与UNIX类似,你应该在命令提示符下显示你想要的不仅仅是命令,而是命令的产物。在UNIX中,它将看起来:
python script.py $(ls home/)
2) 第二个问题是,您的参数将是一个字符串,例如:“file.xml,file.m,file.txt”
,该字符串以.txt
结尾。因此,在这一点上,您将丢失具有所需扩展名的文件
要使其工作,您必须遍历文件列表
files = args.split(",")
for file in files:
main(file)
elif args.dirname.endswith(('.m','.xml'))
不可能工作,如果args必须是字符串,或者您的代码会出错,那么它不可能有两个不同的扩展名,如果用户希望同时选择这两个扩展名,则需要获取一个扩展名元组,例如:
def main(argv):
# make argumentParser return a tuple
args = argumentParser(argv)
if sorted(args) == ('.m', '.xml'):
overrideM()
xmlOverride()
from argparse import ArgumentParser
import os
parser = ArgumentParser()
parser.add_argument("path")
parser.add_argument('ext', nargs='*')
args = parser.parse_args()
path = args.path
exts = args.ext
# what your glob is doing
for f in os.listdir(path):
if f.endswith(tuple(exts)):
with open(os.path.join(path, f)) as fle:
print(fle.name)
# do whatever
更好的选择是使用一个通用函数,该函数接受文件扩展名,只需迭代传入扩展名的参数:
def main(argv):
args = argumentParser(argv)
for ext in args:
generic_search(ext)
无法在字符串上使用args.dirname.endswith(('.m','.xml'))
如果试图匹配这两个参数,则字符串不能同时以.m
和.xml
结尾。我还将路径作为一个参数,将要搜索的扩展名作为单独的参数,然后您可以单独对每个路径进行全局搜索,或者使用str.endswith和多个扩展名,使用os.listdir列出文件
基本思路如下:
def main(argv):
# make argumentParser return a tuple
args = argumentParser(argv)
if sorted(args) == ('.m', '.xml'):
overrideM()
xmlOverride()
from argparse import ArgumentParser
import os
parser = ArgumentParser()
parser.add_argument("path")
parser.add_argument('ext', nargs='*')
args = parser.parse_args()
path = args.path
exts = args.ext
# what your glob is doing
for f in os.listdir(path):
if f.endswith(tuple(exts)):
with open(os.path.join(path, f)) as fle:
print(fle.name)
# do whatever
如果您允许用户搜索多个文件,那么除非您在每个函数中执行非常具体的操作,否则最好使用endswith并在目录上执行一次遍历
如果还要搜索所有子目录以及路径,还可以将其与glob结合使用:
from argparse import ArgumentParser
import os
from glob import iglob
parser = ArgumentParser()
parser.add_argument("path")
parser.add_argument('ext', nargs='*')
args = parser.parse_args()
path = args.path
exts = args.ext
for f in chain.from_iterable([iglob(path+"/*"), iglob(path+"/**/*")]):
if f.endswith(tuple(exts)):
with open(os.path.join(path, f)) as fle:
print(fle.name)
同样,它也适用于多个文件扩展名,只需在目录上传递一次即可。glob适用于单个匹配或几个匹配,但是如果您有多个扩展,那么将listdir和filer与endswith一起使用会更有意义
如果您确实希望为每个扩展使用不同的逻辑,则可以拉动扩展并使用dict调用相应的函数映射扩展名到函数:
from argparse import ArgumentParser
import os
from glob import iglob
def xml(f):
print(f)
def m(f):
print(f)
def text(f):
print(f)
mapped = {"m":m, "xml":xml, "text":text}
parser = ArgumentParser()
parser.add_argument("path")
parser.add_argument('ext', nargs='*')
args = parser.parse_args()
path = args.path
exts = args.ext
for f in chain.from_iterable([iglob(path + "/*"), iglob(path + "/**/*")]):
ext = f.rsplit(".", 1)
if len(ext) == 2 and ext[1] in mapped:
mapped[ext[1]](f)
dict查找是O(1),因此除了简洁之外,它还非常有效
样本输出:
$ python 3_payg.py /home/padraic .xml
/home/padraic/sitemap.xml
/home/padraic/yacy/build.xml
/home/padraic/graphviz-master/graphviz.appdata.xml
至少在Bash中,
*
通配符由shell扩展,而不是由正在运行的进程扩展sys.argv
将包含大量文件。在Windows上可能会有所不同
通过像这样传递要搜索的目录,您会有更好的控制(我跳过argparse,但您应该继续使用它)
并使用来检索文件
import sys
import glob
import os
import itertools
# retreive your directory to expore, from the arguments
# just for the example, better use argparse
dir = sys.argv[1]
# At this point, you might wish to use os.path.abspath & friends
# to have a normalized directory, and check its existence with
# os.path.exists.
# The patterns to search for:
patterns = "*.xml", "*.m"
# a generator expression yielding things like
# "c:\\my\\dir\\*.xml" and "c:\\my\\dir\\*.m"
joint_patterns = (os.path.join(dir, pt) for pt in patterns)
# Glob the joint patterns into a super-generator:
files = itertools.chain.from_iterable( glob.iglob(pt) for pt in joint_patterns )
# Show the result. the '*' is there to evaluate the super generator
# or else it'd print something like
# "<itertools.chain object at 0x7fd92ac9efd0>"
print(*files)
@PadraicCunningham它不会,相反它会给我“Error not find files”你确定argv或args包含任何内容吗?
args.dirname.endswith(('.m','.xml'))
检查以xml
或m
结尾的文件。看来你已经单独检查过了。你又在检查什么呢?实际上运行这两个程序都不起作用,args是什么?它怎么可能以两个不同的扩展名结束呢?请在argsprint(args)
的某个地方登录,以明确现在最多只有3个扩展名。所以我认为glob是一个明智的选择?我也在尝试你的建议和其他建议,希望我能解决它:)@gants,你可以用glob做三遍,或者用os.listdir逻辑做一遍,实际上glob是一个扩展名的理想选择,否则你会检查每个文件*扩展名的数量,使用str.endswidth,您只需通过一次,但如果您没有获得匹配项,则可能会进行相同数量的检查,但这是不太可能的。当您有多个扩展时,listdir逻辑应该是最快的方法。
import sys
import glob
import os
import itertools
# retreive your directory to expore, from the arguments
# just for the example, better use argparse
dir = sys.argv[1]
# At this point, you might wish to use os.path.abspath & friends
# to have a normalized directory, and check its existence with
# os.path.exists.
# The patterns to search for:
patterns = "*.xml", "*.m"
# a generator expression yielding things like
# "c:\\my\\dir\\*.xml" and "c:\\my\\dir\\*.m"
joint_patterns = (os.path.join(dir, pt) for pt in patterns)
# Glob the joint patterns into a super-generator:
files = itertools.chain.from_iterable( glob.iglob(pt) for pt in joint_patterns )
# Show the result. the '*' is there to evaluate the super generator
# or else it'd print something like
# "<itertools.chain object at 0x7fd92ac9efd0>"
print(*files)
import sys
import glob
import os
import itertools
# retreive your directory to expore, from the arguments
# just for the example, better use argparse
dir = sys.argv[1]
# The patterns to search for:
patterns = "*.xml", "*.m"
# a LIST holding things like
# "c:\\my\\dir\\*.xml" and "c:\\my\\dir\\*.m"
joint_patterns = [os.path.join(dir, pt) for pt in patterns]
# Glob iterators.
globs = [glob.iglob(pt) for pt in joint_patterns]
for xml_file_path in globs[0]:
do_xml_stuff(xml_file_path)
for m_file_path in globs[1]:
do_m_stuff(m_file_path)