How to redirect 'print' output to a file using python?


Question

I want to redirect the print to a .txt file using python. I have a 'for' loop, which will 'print' the output for each of my .bam file while I want to redirect ALL these output to one file. So I tried to put

 f = open('output.txt','w'); sys.stdout = f

at the beginning of my script. However I get nothing in the .txt file. My script is:

#!/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....

So what's the problem? Any other way besides this sys.stdout?

I need my result look like:

Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
1
141
12/3/2017 5:13:46 PM

Accepted Answer

The most obvious way to do this would be to print to a file object:

with open('out.txt', 'w') as f:
    print >> f, 'Filename:', filename     # Python 2.x
    print('Filename:', filename, file=f)  # Python 3.x

However, redirecting stdout also works for me. It is probably fine for a one-off script such as this:

import sys

orig_stdout = sys.stdout
f = open('out.txt', 'w')
sys.stdout = f

for i in range(2):
    print 'i = ', i

sys.stdout = orig_stdout
f.close()

Redirecting externally from the shell itself is another good option:

./script.py > out.txt

Other questions:

What is the first filename in your script? I don't see it initialized.

My first guess is that glob doesn't find any bamfiles, and therefore the for loop doesn't run. Check that the folder exists, and print out bamfiles in your script.

Also, use os.path.join and os.path.basename to manipulate paths and filenames.

205
12/17/2018 5:50:14 PM

You can redirect print with the >> operator.

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

In most cases, you're better off just writing to the file normally.

f.write('whatever')

or, if you have several items you want to write with spaces between, like print:

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

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon