我想使用python将打印重定向到.txt文件 . 我有一个'for'循环,它会'打印'我的每个.bam文件的输出,而我想将所有这些输出重定向到一个文件 . 所以我试着把
f = open('output.txt','w'); sys.stdout = f
在我的脚本开头 . 但是我在.txt文件中什么都没得到 . 我的脚本是:
#!/usr/bin/python
import os,sys
import subprocess
import glob
from os import path
f = open('output.txt','w')
sys.stdout = f
path= '/home/xug/nearline/bamfiles'
bamfiles = glob.glob(path + '/*.bam')
for bamfile in bamfiles:
filename = bamfile.split('/')[-1]
print 'Filename:', filename
samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
stdout=subprocess.PIPE,bufsize=1)
linelist= samtoolsin.stdout.readlines()
print 'Readlines finished!'
........print....
........print....
所以有什么问题?除了这个sys.stdout之外的任何其他方式?
我需要我的结果如下:
Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
10 回答
最明显的方法是打印到文件对象:
但是,重定向stdout对我也有用 . 这对于像这样的一次性脚本来说可能很好:
脚本中的第一个文件名是什么?我没有看到它初始化 .
我的第一个猜测是glob没有找到任何bamfiles,因此for循环不会运行 . 检查文件夹是否存在,并在脚本中打印出bamfiles .
另外,使用os.path.join and os.path.basename来操作路径和文件名 .
您可以使用
>>
运算符重定向打印 .在大多数情况下,您最好只是正常写入文件 .
或者,如果你想要用多个空格写几个项目,比如
print
:由于file object通常包含
write()
方法,因此您需要做的就是将file object传递给其参数 .写入/覆盖文件
写入/附加到文件
这非常有效:
现在hello将被写入test.txt文件 . 确保用
close
关闭stdout
,没有它,内容将不会保存在文件中最简单的解决方案不是通过python;它通过壳 . 从您文件的第一行(
#!/usr/bin/python
)开始,我在UNIX系统上运行 . 只需像往常一样使用print
语句,并且不要在脚本中打开文件 . 当你去运行文件时,而不是要运行该文件,请使用
将
<filename>
替换为您希望输出进入的文件的名称 .>
令牌告诉(大多数)shell将stdout设置为由以下标记描述的文件 .这里需要提到的一件重要事情是"script.py"需要被设置为可执行
./script.py
才能运行 .因此,在运行
./script.py
之前,请执行此命令chmod a+x script.py
(使脚本可执行所有用户)不要使用打印,请使用日志记录
您可以将
sys.stdout
更改为指向文件,但这是一种非常笨重且不灵活的方法来处理此问题 . 而不是使用print
,使用logging模块 .使用
logging
,您可以像stdout
一样进行打印,或者也可以将输出写入文件 . 您甚至可以使用不同的消息级别(critical
,error
,warning
,info
,debug
),例如,仅将主要问题打印到控制台,但仍将次要代码操作记录到文件中 .一个简单的例子
导入
logging
,获取logger
,并设置处理级别:如果要打印到标准输出:
如果你还想写一个文件(如果你只想写一个文件跳过最后一节):
然后,无论你在哪里使用
print
,都要使用logger
方法之一:要了解有关使用更高级的
logging
功能的更多信息,请阅读优秀的logging tutorial in the Python docs .你可能不喜欢这个答案,但我认为这是正确的答案 . 除非绝对必要,否则不要更改你的stdout目的地(也许你正在使用一个只输出到stdout的库?显然不是这里的情况) .
我认为,作为一个好习惯,您应该提前准备数据作为字符串,然后打开您的文件并立即编写整个文件 . 这是因为输入/输出操作是打开文件句柄的时间越长,此文件发生错误的可能性就越大(文件锁定错误,i / o错误等) . 只需在一次操作中完成所有操作就可以确定何时出错 .
这是一个例子:
然后当你完成每个列表项的一行收集"data lines"时,你可以用一些
'\n'
字符加入它们,使整个事物可输出;甚至可以将输出语句包装在with
块中,以增加安全性(即使出现问题也会自动关闭输出句柄):但是,如果要写入大量数据,则 could 一次写入一个数据 . 我没有't think it'与您的申请相关,但这里是替代方案:
更改sys.stdout的值确实会更改目标所有打印电话 . 如果您使用其他方法更改打印目的地,您将获得相同的结果 .
你的错误在别的地方:
它可能在你为你的问题删除的代码中(文件名来自哪里打开调用?)
也可能是您没有等待刷新数据:如果在终端上打印,则在每个新行之后刷新数据,但如果打印到文件,则仅在stdout缓冲区已满时刷新(4096)大多数系统上的字节数) .
如果你使用linux我建议你使用
tee
命令实现就像这个pythonpython_file.py |tee any_file_name.txt
如果你不想改变代码中的任何东西,我认为这可能是最好的解决方案,你也可以实现 Logger ,但你需要做一些改变在代码中 .用于扩展循环的打印功能的东西