如何用stdin stdout替换命令行参数sys.argv?

时间:2014-02-20 13:23:12

标签: python stdout stdin sys

我意识到,我的问题非常简单,但我找不到任何将stdin stdout实现为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

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

  
    

cat input1 input1 input3 | myscript.py

  

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

filename = sys.stdin
filename_out = sys.stdout

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

  
    

./ myscript.py&lt; inputfile&gt; OUTPUTFILE

  

导致输出文件为空,但根本没有输出任何错误消息。

你可以帮我替换一下吗?

P.S。然后我修改了我的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

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

1 个答案:

答案 0 :(得分:3)

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树,如果可能的话(例如,只读取一次文件,然后从那里使用解析后的结构),那就更好了。