【问题标题】:How to replace command line arguments sys.argv by stdin stdout?如何用标准输入标准输出替换命令行参数 sys.argv?
【发布时间】:2014-02-20 13:23:11
【问题描述】:

我意识到,我的问题是一个非常简单的问题,但我找不到任何将 stdin 标准输出实现为 Python 脚本的明确示例。

我有一个脚本,可以很好地使用命令行参数:

newlist = []
def f1()
  .... 
def f2(input_file):
  vol_id = sys.argv[3]
  for line in input_file:
      if ... :
        line = line.replace('abc','def')
        line = line.replace('id', 'id'+vol_id)
      ....
      newlist.append(line)
   return newlist

def main():
    if len(sys.argv) < 4:
       print 'usage: ./myscript.py [file_in... file_out... volume_id]'
       sys.exit(1)

    else:

        filename = sys.argv[1]
        filename_out = sys.argv[2]


        tree = etree.parse(filename)
        extract(tree)

        input_file = open(filename, 'rU')
        change_class(input_file)

        file_new = open(filename_out, 'w')
        for x in newlist:

            if '\n' in x:                   
               x = x.replace('\n', '')                
            print>>file_new, x

现在我应该以某种方式使用标准输入和标准输出而不是我的参数,以使我的脚本在管道中可用,例如使用多个文件作为输入:

cat 输入1 输入1 输入3 |我的脚本.py

或者在将其打印到文件之前使用一些 UNIX 工具处理其输出。 我试图用 sys.stdin 替换脚本中的参数:

filename = sys.stdin
filename_out = sys.stdout

然后我像这样运行我的脚本:

./myscript.py 输出文件

它导致一个空的输出文件,但根本没有产生任何错误消息。

您能帮我解决这个问题吗?

附:然后我像这样修改了我的 main():

filename = sys.argv[1]
filename_out = sys.argv[2]

if filename == '-':
   filename = sys.stdin
else:
    input_file = open(filename, 'rU')


if filename_out == '-':
    filename_out = sys.stdout
    file_new = filename_out
else:
    file_new = open(filename_out, 'w')


tree = etree.parse(filename)
extract(tree)

input_file = filename
change_class(input_file)

for x in newlist:

    if '\n' in x:                   
       x = x.replace('\n', '')                
    print>>file_new, x

我尝试像这样从命令行运行它:

./myscript.py - - volumeid < filein > fileout

但我仍然得到一个空的输出文件:(

【问题讨论】:

  • 您可能会发现fileinput 模块很有用(在标准库中)。
  • @cdarke: fileinput 非常适合您只有输入文件的情况。您仍然需要手动处理命令行参数并传入 fileinput 应明确视为输入的文件。

标签: python stdout stdin sys


【解决方案1】:

stdinstdout 的常用占位符是-

./myscript.py - - volumeid

和:

if filename == '-':
    input_file = sys.stdin
else:
    input_file = open(filename, 'rU')

等等

此外,当命令行参数少于 3 个时,您可以默认 filenamefilename_out-。您应该考虑使用专用的命令行参数解析器,例如argparse,它可以为您处理这些情况,包括默认为stdinstdout,以及使用-

附带说明,我不会使用print 写入文件;我只是使用:

file_new.write(x)

这也消除了删除换行符的需要。

您似乎从输入文件中读取了两次;一次解析 XML 树,再次使用打开的文件对象调用 change_class()。你想在那里做什么?使用 sys.stdin 复制它时会遇到问题,因为您无法像从磁盘上的文件中那样从流中重新读取数据。

您必须先将所有数据读入内存,然后从中解析 XML,然后再为change_class() 读取它。如果可能的话,最好使用已解析的 XML 树来代替(例如,只读取一次文件,然后从那里使用已解析的结构)。

【讨论】:

  • 评论不是发布代码的最佳位置。如果后续问题涉及的不仅仅是一个小的澄清,则可能需要提出一个新问题。
  • 没错!这就是为什么我把我的代码作为答案放在下面
  • 啊,使用实际答案!
  • 和相同票数的答案是随机排序的,所以我没有看到你的答案“低于”而是“高于”。
  • 好的,问题已修改
猜你喜欢
  • 2010-09-13
  • 2014-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
  • 2016-08-09
  • 2021-04-29
  • 1970-01-01
相关资源
最近更新 更多