无需手动输入即可读取文件名列表

时间:2014-12-03 00:44:23

标签: python

我有一个python代码,其中使用输入命令

接收文件名

fileName = input("请输入文件名")

我的目的是编写一个脚本来运行此文件。但我不想坐在那里手动输入每个文件名。是否可以在运行时将fileName作为命令行参数提供。

编辑:更多解释:我给出了上面一行的python代码,我应该在一些示例输入上运行。我不想更改文件或示例输入只想在输入上自动运行文件。原因是需要检查许多文件和许多样本输入。

4 个答案:

答案 0 :(得分:2)

你有几个选择,真的。

将stdin重定向到文件

您可能没有考虑过的是将程序保留原样,创建带有文件名列表的文本文件,然后将标准输入重定向到文件。让我们将文件命名为myfilelist.txt。该文件只是一个列表:

~/file1.txt
~/file2.txt

或在Windows上:

C:\file1.txt
C:\file2.txt

然后你会这样打电话给你的程序:

python ./myprogram.py < ./myfilelist.txt

此处,<字符告诉操作系统使用myfilelist.txt的内容而不是等待您键入。这确实假设你的程序循环并继续提示输入多个文件。

如果它一次只接受一个文件,那么您可以考虑......

使用脚本

您可以编写一个脚本,分别多次调用您的程序,每次使用不同的文件名。 Linux上的bash脚本可能如下所示:

#!/bin/bash
echo '~/file1.txt' | python ./myprogram.py
echo '~/file2.txt' | python ./myprogram.py

或Windows上的批处理文件:

echo C:\file1.txt | python .\myprogram.py
echo C:\file2.txt | python .\myprogram.py

在这里,我们执行命令echo以使系统&#34; print&#34;输出一些文本,然后我们使用|(管道)告诉系统使用echo的输出作为其他程序的输入(而不是将文本打印到屏幕)。

列出文件参数

另一种选择是为程序创建一个接受单个文件路径的参数,然后将该文件的内容用作要处理的文件列表。这需要修改你的程序。

在代码中执行此操作的快速而肮脏的方法:

import sys
if '__main__' == __name__:
    list_file = sys.argv[1]
    with open(list_file) as f:
        for r in f:
            do_my_other_code(r)

然后你就这样称呼它:

python ./myprogram.py ./myfilelist.txt

查看argparsegetopt或类似内容,以使其更清洁。

参数列表

您可以将所有文件列为原始命令的一部分。您的代码看起来像这样:

import sys
if '__main__' == __name__:
    for a in sys.argv[1:]:
        do_my_other_code(a)

(请注意,sys.argv[1:]被称为&#34;切片&#34;。如果您不熟悉它们,请查看它。)

然后你会这样称呼:

python ./myprogram.py ~/file1.txt ~/file2.txt

我并不特别喜欢这个选项,因为你的问题表明你有一个相当大的文件列表。键入命令将是乏味且容易出错的。如果计算机崩溃或其他什么,你也不会在任何地方保存列表。但它只适用于几个文件。

其他

有很多方法可以做这样的事情。这些只是一些相当简单的选择。 最佳一个将取决于您的确切用法。

答案 1 :(得分:1)

import sys

if len(sys.argv) > 0
    filename = str(sys.argv[1])

或类似的东西

答案 2 :(得分:1)

您可以使用argparse。例如

<强> test.py

import argparse


def main():

    in_args = _argparse()

    print(in_args)

    for a_file in in_args.file:
        ...
        #do_soomthing_with_a_file(a_file)


def _argparse():

    parser = argparse.ArgumentParser()
    parser.add_argument("file",   help="input files", type=str, nargs='+')

    args = parser.parse_args()

    return args


if __name__ == '__main__':
    main()

然后从命令行:

# a single file
marcin:test$ python test.py ./data.csv 
Namespace(file=['./data.csv'])

# multiple files
marcin:test$ python test.py ./*.* 
Namespace(file=['./data.csv', './test.py'])

# other example of multiple input files
marcin:test$ python test.py ./test.py ./data.csv 
Namespace(file=['./test.py', './data.csv'])

答案 3 :(得分:0)

如果要将文件名或1个或多个文件名作为命令行参数,可以使用argv手动执行此操作:

import sys

for filename in sys.argv[1:]:
    with open(filename) as f:
        for line in f:
            do_stuff_with(line)

...或使用argparse,如Marcin's answer所示 - 更多工作,但更灵活。

但是,如果你对这些文件做的唯一事情是打开它们并逐行读取它们,那么使用fileinput可能会更简单。例如:

import fileinput

for line in fileinput.input():
    do_stuff_with(line)

默认情况下,fileinput.input查看argv并逐个打开每个指定的文件,如果没有指定文件,则从stdin读取。所以,当你想做什么时,它可以简化你的代码。