我意识到,我的问题非常简单,但我找不到任何将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
但我仍然有一个空的输出文件:(
答案 0 :(得分:3)
stdin
或stdout
的常见占位符为-
:
./myscript.py - - volumeid
和
if filename == '-':
input_file = sys.stdin
else:
input_file = open(filename, 'rU')
等
此外,当命令行参数少于3时,您可以将filename
和filename_out
默认为-
。您应该考虑使用专用的命令行参数解析器,例如argparse
,它可以为您处理这些情况,包括默认为stdin
和stdout
,以及使用-
。
作为旁注,我不会使用print
来写入文件;我只是用:
file_new.write(x)
这也消除了剥离换行符的需要。
您似乎从输入文件中读取了两次;一次解析XML树,再次使用打开的文件对象调用change_class()
。你想在那里做什么?使用sys.stdin
复制时会遇到问题,因为您无法从磁盘上的文件中重新读取数据。
您必须首先将所有数据读入内存,然后从中解析XML,然后再次为change_class()
读取它。如果你使用解析的XML树,如果可能的话(例如,只读取一次文件,然后从那里使用解析后的结构),那就更好了。