【问题标题】:Reading the contents of a piped input file in Python program在 Python 程序中读取管道输入文件的内容
【发布时间】:2019-11-15 15:00:20
【问题描述】:

我必须读取已通过管道传输到 Python 程序中的文本文件的内容。文件到输入文件可以按如下方式传递

  1. 您的程序必须接受来自两个来源的输入:在命令行参数中传递的文件名和 STDIN。例如,在 Linux 或 OSX 上,./myprogram input.txt./myprogram < input.txt 都应该可以工作。

我不知道该怎么做。

if __name__ == '__main__': 
  # I don't know what to do here.

输入文件有以下几行,每一行都需要解析。

Add Tom 4111111111111111 $1000
Add Lisa 5454545454545454 $3000
Add Quincy 1234567890123456 $2000
Charge Tom $500
Charge Tom $800
Charge Lisa $7
Credit Lisa $100
Credit Quincy $200

每当我尝试python myprogram.py > input.txt 时,程序就会挂起。如果有帮助,我正在使用 Python 3.6.5。

更新:

我尝试了一些类似的方法:

(env) myproject (master) $ python main.py > test.txt
testing testing testing
1 2 3
1 2 3

如果文件不存在,则创建一个新文件,或者用输入的内容覆盖现有文件。在这种情况下,使用上述内容创建了一个名为 test.txt 的新文件。

更新 #2

我试过这样的

if __name__ == '__main__':
  for line in sys.stdin.readline():
      print (line)

对于这样的单行

Add Tom 4111111111111111 $1000

每个字符都显示在一个新行中

A
d
d

T
o
m

. . .

我希望所有字符都打印在一行上。

【问题讨论】:

  • 注意<>在shell中的含义不同。 < 重定向标准输入,> 重定向标准输出。通过执行python myprogram.py > input.txt,您将让shell 将python 脚本的输出重定向到文件input.txt。如果您的程序不打印任何内容,它将创建一个空文件。它还将覆盖文件的任何现有内容。
  • python myprogram.py < input.txt > out.txt 从 input.txt 读取并写入 out.txt
  • @AdamBurke 我已经用我的发现更新了我的帖子。
  • 现在你已经将字符放入一个名为 line 的变量中......你必须对它们做一些事情,也许通过将它们传递给函数和其他操作,然后再传递你想要的输出到print()。接下来也许可以尝试编写一个parse() 函数。
  • 在 stdin / stdout 部分,请注意它们都是 python 中的类文件对象。因此,您通常可以查看传递的参数数量,并使用它来确定是使用文件名还是标准输入,然后将其传递,就像@john-gordon 所说的那样

标签: python-3.x stdin


【解决方案1】:

这对我来说效果最好。 https://docs.python.org/3/library/fileinput.html

这会遍历 sys.argv[1:] 中列出的所有文件的行,如果列表为空,则默认为 sys.stdin

经过一番反复试验,这就是我想出的

def handle_command_line_inputs():
    """Read the contents of the file piped through the command line.

    Once the operations are executed, then the balance is ready to be displayed
    """
    logging.info('Reading from the file')
    for line in fileinput.input():
        print(line)
        # My custom logic

这会打印每一行。

在我的单元测试中

from unittest import mock


def get_test_file():
    current_path = os.path.dirname(os.path.realpath(__file__))
    return os.path.normpath(os.path.join(current_path, 'input.txt'))


def read_input_file():
    """Simulates the generators that read file contents."""
    input_file = get_test_file()
    with open(input_file, 'r') as f:
        for line in f:
            yield line


@mock.patch('fileinput.input', side_effect=read_input_file)
def test_handle_command_line_inputs(mocked_fileinput):

    myprogram.handle_command_line_inputs()
    # Run your assertions.

【讨论】:

    【解决方案2】:

    sys.argv 是一个包含调用程序的参数(如果有)的列表。

    如果它是一个元素长,那么你的程序在没有任何参数的情况下被调用(脚本名称本身是第一个参数,所以它并不真正计算在内),因此你应该阅读sys.stdin

    否则,如果它有两个或更多元素,您的程序会以文件名作为参数调用,因此您应该打开该文件并将其用作输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      相关资源
      最近更新 更多