如果一个目录同时包含'.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,反之亦然。请注意,如果用户只想要“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"
我的''功能(小部分)
def overrideM(args):
for fileName in glob.glob(args.dirname):
print fileName
with open(fileName, 'r') as searchFile:
my_files_content = searchFile.read()
#...rest of my code
我的'XML'功能(小部分)
def xmlOverride(args):
for fileName in glob.glob(args.dirname):
print fileName
with open(fileName, 'r') as searchFile:
my_files_content = searchFile.read()
#...rest of my code
答案 0 :(得分:1)
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()
更好的选择是使用一个带有文件扩展名的泛型函数,只是迭代传入扩展名的args:
def main(argv):
args = argumentParser(argv)
for ext in args:
generic_search(ext)
如果您尝试匹配字符串,则无法在字符串上使用args.dirname.endswith(('.m', '.xml'))
,字符串根本无法在.m
和.xml
中结束。我还将路径作为一个arg和扩展来搜索单独的args,然后你可以单独地为每个arbase或使用带有多个扩展的 str.endswith 使用os.listdir列出文件。
基本理念如下:
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
答案 1 :(得分:0)
1)我与MS Windows
没有很大的友谊,但无论如何它与UNIX
相似,你可能会在命令提示符下显示你想要的命令产品不仅仅是命令。在UNIX中它将看起来:
python script.py $(ls home/)
2)第二个问题是你args将是一个字符串,例如:"file.xml, file.m, file.txt"
,例如此字符串以.txt
结尾。因此,您将错过具有所需扩展名的文件。
要使其工作,您必须迭代文件列表。
files = args.split(",")
for file in files:
main(file)
答案 2 :(得分:0)
至少在Bash中,{:var "I am a var"}
通配符由 shell 扩展,而不是正在运行的进程。 *
将包含大量文件。在Windows上可能会有所不同。
你可以通过将目录传递给像这样的搜索来更好地控制(我跳过argparse,但是你应该继续使用它)。
sys.argv
并使用glob or iglob来检索文件。
myscript.py c:\a\directory
这个解决方案的缺点是你不会受益于你的shell关于通配符的花哨设施。
在您的情况下,您不需要使用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)
创建超级生成器。您只需检索每个模式的glob迭代器:
chain