使用通配符将参数传递给Python脚本

19

我想做类似这样的事情:

c:\data\> python myscript.py *.csv

我希望将目录中所有的.csv文件传递给我的Python脚本(使得sys.argv包含["file1.csv", "file2.csv"]等)。

但是sys.argv只收到["*.csv"],表明通配符没有被扩展,因此这样做不起作用。

我觉得有一种简单的方法可以做到这一点,但在Google上找不到。 有什么想法吗?

4个回答

26
你可以使用glob模块,这样你就不会依赖于特定shell的行为(好吧,你仍然需要依赖shell不扩展参数,但至少你可以通过转义通配符在Unix中实现这一点 :-))。
from glob import glob
filelist = glob('*.csv') #You can pass the sys.argv argument

不是“可以”,对于Windows来说,这是“必须”的。 - S.Lott
嗯,你也可以使用os.walk,所以这不是严格必须的:P - Vinko Vrsalovic
@Vinko Vrsalovic:没错。os.walk似乎比glob更繁琐。虽然不需要Glob,但它非常适合解决这个问题。 - S.Lott
2
正是我所需要的 :) - 1.01pm
有人知道为什么Windows shell不会自动处理这个吗? - Ryan Thames
显示剩余2条评论

17

在Unix中,shell会扩展通配符,因此程序会得到已扩展的文件名列表。而Windows不会这样做:shell会将通配符直接传递给程序,程序自己必须进行扩展。

Vinko是正确的:glob模块可以完成这个任务:

import glob, sys

for arg in glob.glob(sys.argv[1]):
    print "Arg:", arg

请注意:如果sys.argv[1]是一个完全指定的文件名而不是通配符,这也可以完美地工作。在这种情况下,glob.glob会返回一个只包含该文件名的列表。 - Florian Brucker
如果您将参数转发到Python脚本script.py c:\path\*\subdir,glob会生成一个列表,以便稍后使用。这是一个很棒的模块! - Stefatronik

1
如果您传入了多个通配符项(例如:python myscript.py *.csv *.txt),则glob(sys.argv[1]可能无法满足需求。您可能需要像下面这样的东西。
import sys
from glob import glob

args = [f for l in sys.argv[1:] for f in glob(l)]

即使某些参数中没有通配符,这也可以正常工作。(python abc.txt *.csv anotherfile.dat


我以前从未见过在单个列表推导式中使用两个for...in的情况。那里发生了什么? - Prometheus2508

0
如果您的脚本是一个实用程序,我建议您在.bashrc中定义一个函数来调用它:
myscript() {
   python /path/myscript.py "$@"
}

然后整个列表将传递到您的Python中,您可以像这样处理它们:

for _file in sys.argv[1:]:
    # do something on file

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接