我想使用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/xxx/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!'

那么问题是什么呢?除了sys。stdout还有其他方法吗?

我需要我的结果看起来像:

Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)

当前回答

最简单的解决方案不是通过python;它穿过外壳。从文件的第一行(#!/usr/bin/python),我猜您是在UNIX系统上。只需像平时一样使用print语句,在脚本中完全不要打开文件。当你运行文件时,而不是

./script.py

要运行该文件,请使用

./script.py > <filename>

您将<filename>替换为您希望输出进入的文件的名称。>令牌告诉(大多数)shell将stdout设置为以下令牌所描述的文件。

这里需要提到的一件重要的事情是,“script.py”需要被设置为可执行的,以便。/script.py能够运行。

所以在运行。/script.py之前,执行这个命令

Chmod a+x script.py (使脚本对所有用户都可执行)

其他回答

我在过去用来输出一些字典的东西如下:

# sample dictionary
the_dict = {'a': 'no', 'c': 'yes', 'b': 'try again'}

# path to output to
dict_path = "D:/path.txt"

# script to output file
with open(dict_path, "w") as f:
    for idx, data in the_dict.items():
        print(idx, data, file=f)

输出的文件如下所示:

a no
c yes
b try again

我能够破解这个使用以下方法。它将使用这个打印函数而不是内置的打印函数,并将内容保存到一个文件中。

from __future__ import print_function
import builtins as __builtin__

log = open("log.txt", "a")

def print(*args):
    newLine = ""
    for item in args:
        newLine = newLine + str(item) + " "
    newLine = (
        newLine
        + """
"""
    )
    log.write(newLine)
    log.flush()
    __builtin__.print(*args)
    return

你可能不喜欢这个答案,但我认为这是正确的答案。除非绝对必要,否则不要改变你的标准输出目标(也许你使用的库只输出到标准输出??这里显然不是这样)。

我认为作为一个好习惯,你应该提前准备好你的数据作为一个字符串,然后打开你的文件,并立即写入整个东西。这是因为输入/输出操作打开文件句柄的时间越长,该文件发生错误的可能性就越大(文件锁定错误、i/o错误等)。只要在一次操作中完成所有操作,就不会有什么时候可能出错的问题。

这里有一个例子:

out_lines = []
for bamfile in bamfiles:
    filename = bamfile.split('/')[-1]
    out_lines.append('Filename: %s' % filename)
    samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
                                  stdout=subprocess.PIPE,bufsize=1)
    linelist= samtoolsin.stdout.readlines()
    print 'Readlines finished!'
    out_lines.extend(linelist)
    out_lines.append('\n')

然后,当你收集了你的“数据线”,每个列表项一行,你可以用一些'\n'字符连接它们,使整个东西可输出;甚至可以将输出语句包装在with块中,以获得额外的安全性(即使出现错误,也会自动关闭输出句柄):

out_string = '\n'.join(out_lines)
out_filename = 'myfile.txt'
with open(out_filename, 'w') as outf:
    outf.write(out_string)
print "YAY MY STDOUT IS UNTAINTED!!!"

然而,如果你有很多数据要写,你可以一次写一块。我认为这与你的应用程序无关,但这里有另一种选择:

out_filename = 'myfile.txt'
outf = open(out_filename, 'w')
for bamfile in bamfiles:
    filename = bamfile.split('/')[-1]
    outf.write('Filename: %s' % filename)
    samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
                                  stdout=subprocess.PIPE,bufsize=1)
    mydata = samtoolsin.stdout.read()
    outf.write(mydata)
outf.close()

如果您正在使用Linux,我建议您使用tee命令。实现如下所示:

python python_file.py | tee any_file_name.txt

如果您不想更改代码中的任何内容,我认为这可能是最好的解决方案。您也可以实现记录器,但您需要在代码中做一些更改。

你可以用file参数重定向打印(在python2中有>>操作符代替)。

f = open(filename,'w')
print('whatever', file=f) # Python 3.x
print >>f, 'whatever'     # Python 2.x

在大多数情况下,最好只是正常地写入文件。

f.write('whatever')

或者,如果你有几个项目想用空格写,比如print:

f.write(' '.join(('whatever', str(var2), 'etc')))