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
Something to extend print function for loops
x = 0
while x <=5:
x = x + 1
with open('outputEis.txt', 'a') as f:
print(x, file=f)
f.close()
If you are using Linux I suggest you to use the tee
command. The implementation goes like this:
python python_file.py | tee any_file_name.txt
If you don't want to change anything in the code, I think this might be the best possible solution. You can also implement logger but you need do some changes in the code.
If redirecting stdout
works for your problem, Gringo Suave's answer is a good demonstration for how to do it.
To make it even easier, I made a version utilizing contextmanagers for a succinct generalized calling syntax using the with
statement:
from contextlib import contextmanager
import sys
@contextmanager
def redirected_stdout(outstream):
orig_stdout = sys.stdout
try:
sys.stdout = outstream
yield
finally:
sys.stdout = orig_stdout
To use it, you just do the following (derived from Suave's example):
with open('out.txt', 'w') as outfile:
with redirected_stdout(outfile):
for i in range(2):
print('i =', i)
It's useful for selectively redirecting print
when a module uses it in a way you don't like. The only disadvantage (and this is the dealbreaker for many situations) is that it doesn't work if one wants multiple threads with different values of stdout
, but that requires a better, more generalized method: indirect module access. You can see implementations of that in other answers to this question.
The easiest solution isn't through python; its through the shell. From the first line of your file (#!/usr/bin/python
) I'm guessing you're on a UNIX system. Just use print
statements like you normally would, and don't open the file at all in your script. When you go to run the file, instead of
./script.py
to run the file, use
./script.py > <filename>
where you replace <filename>
with the name of the file you want the output to go in to. The >
token tells (most) shells to set stdout to the file described by the following token.
One important thing that needs to be mentioned here is that "script.py" needs to be made executable for ./script.py
to run.
So before running ./script.py
,execute this command
chmod a+x script.py
(make the script executable for all users)
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.