如何将可变数量的文件作为python脚本的输入?

时间:2014-06-20 16:27:46

标签: python shell python-2.7 command-line command-line-arguments

例如,我希望能够运行这个假设的命令:

$ python script.py *.txt option1 option2

让它在每个匹配* .txt

的文件上执行

目前我只找到有关一次操作一个文件的信息

from sys import argv

self, file, option1, option2 = argv

perform_operation(file, option1, option2)

#function definition

4 个答案:

答案 0 :(得分:3)

您想使用argparse-module:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("--option1")
parser.add_argument("--option2")
parser.add_argument("files", nargs="+")

opts = parser.parse_args()

print opts.option1
print opts.option2
print opts.files

像这样使用:

 beer:~ deets$ python2.7 /tmp/argparse-test.py  text foo bar baz
 None
 None
 ['text', 'foo', 'bar', 'baz']

答案 1 :(得分:1)

argv是一个列表。让我们假设你只是要传递文件名参数。如果它更复杂,那么请选择deets'答案。

self = sys.argv[0]
arguments = sys.argv[1:]

现在,arguments是程序参数列表。让我们说我们想要一次处理一个:

for argument in arguments:
    work(argument)

或者我们想将所有这些传递给函数:

work(arguments)

关于传递*.txt作为参数。你的shell(在程序运行之前)将为你完成大部分工作。

如果我运行,python program.py *.txt其中*.txt指的是3个文本文件,那么我的shell会展开,以便我的程序看到python program.py a.txt b.txt c.txt

答案 2 :(得分:1)

multifile.py

"""
Usage:
    multifile.py <file>...
    multifile.py -h

Prints something about all the <file>... files.
"""

def main(files):
    for fname in files:
        print fname

if __name__ == "__main__":
    from docopt import docopt
    args = docopt(__doc__)
    files = args["<file>"]
    main(files)

使用

首先安装docopt

$ pip install docopt

不带参数调用命令:

$ python multifile.py
Usage:
    multifile.py <file>...
    multifile.py -h

尝试帮助

$ python multifile.py -h
Usage:
    multifile.py <file>...
    multifile.py -h

Prints something about all the <file>... files.

将它用于一个文件:

$ python multifile.py alfa.py 
alfa.py

使用通配符将其用于多个文件:

$ python multifile.py ../*.py

    ../camera2xml.py
    ../cgi.py
    ../classs.py

结论

  • docopt允许更多选项(请参阅docopt
  • 命令行解析在Python中很容易
    • argparse似乎是自2.7版本以来Python的标准部分。
    • argparse可以做很多事,但需要在很多行上进行相当复杂的调用
    • plac是不错的选择,在大多数情况下可以快速服务
    • docopt在我看来是最灵活的,同时也是所需代码行中最短的

答案 3 :(得分:0)

使用stdlib中的inputfile

stdlib中有一个库,经常被忽略,称为inputfile

它默认处理命令行上的所有输入或作为文件名从stdin处理,并且不仅可以迭代这些文件,还可以遍历其中的所有行,修改它们,解压缩以及许多其他实际操作。

filenames.py - 列出所有文件名

import fileinput

for line in fileinput.input():
    print "File name is: ", fileinput.filename()
    fileinput.nextfile()

称之为:

$ python filenames.py *.txt
File name is: films.txt
File name is: highscores.txt
File name is: Logging.txt
File name is: outtext.txt
File name is: text.txt

upperlines.py - 以大写

打印多个文件中的所有行
import fileinput

for line in fileinput.input():
    print line.upper(),

并称之为:

$ python upperlines.py *.txt
THE SHAWSHANK REDEMPTION (1994)
THE GODFATHER (1972)
THE GODFATHER: PART II (1974)
THE DARK KNIGHT (2008)
PULP FICTION (1994)
JAN HAS SCORE OF 101
PIETER HAS SCORE OF 900
CYRIL HAS SCORE OF 2
2014 APR 11  07:14:03.155  SECTORBLAH
   INTERESTINGCONTENT
   INTERESTING1 = 843
1. LUV_DEV <- HE'S A DEVELOPER
2. AMIT_DEV <- HE'S A DEVELOPER
....

upperlinesinplace.py - 将文件中的所有行转换为大写

import fileinput

for line in fileinput.input(inplace=True):
    print line.upper(),

结论

  • fileinput采用默认参数sys.argv[:1]并迭代所有文件和行
  • 您可以传递自己的文件名列表以进行处理
  • fileinput允许就地更改,过滤,读取文件名,行号...
  • fileinput甚至允许处理压缩文件