23

I'd like to query items from a dict and save the printed output to a text file.

Here's what I have:

import json
import exec.fullog as e

inp = e.getdata() #inp now is a dict() which has items, keys and values.

#Query

print('Data collected on:', inp['header']['timestamp'].date())
print('\n CLASS 1 INFO\n')

for item in inp['Demographics']:
    if item['name'] in ['Carly', 'Jane']:
        print(item['name'], 'Height:', item['ht'], 'Age:', item['years'])

for item in inp['Activity']:
    if item['name'] in ['Cycle', 'Run', 'Swim']:
        print(item['name'], 'Athlete:', item['athl_name'], 'Age:', item['years'])
Buddy Bob
  • 5,829
  • 1
  • 13
  • 44
Ironfist
  • 243
  • 1
  • 2
  • 4
  • Seems to be a duplicated of https://stackoverflow.com/questions/4110891/how-to-redirect-the-output-of-print-to-a-txt-file – JuanDeLosMuertos Jun 19 '19 at 13:59
  • Simply, continue printing whatever you want, to the cosole just like you do using `print` or `log` within the Python file; no specific change here. Now, while executing the python file `python3 yo.py`, simply replace the command with `python3 yo.py > logs.txt` – Pe Dro May 04 '20 at 07:14

12 Answers12

24

abarnert's answer is very good and pythonic. Another completely different route (not in python) is to let bash do this for you:

$ python myscript.py > myoutput.txt

This works in general to put all the output of a cli program (python, perl, php, java, binary, or whatever) into a file, see How to save entire output of bash script to file for more.

If you want the output to go to stdout and to the file, you can use tee:

$ python myscript.py | tee myoutput.txt

For more on tee, see: How to redirect output to a file and stdout

metaperture
  • 2,393
  • 1
  • 18
  • 19
  • 1
    Actually, this is even more universally usable: simple `>` redirection works on Windows, and on almost all *nix shells, not just bash. – abarnert Jul 29 '14 at 19:59
  • Thanks @abarnert, I'm blissfully unaware of Windows cmd, but I sit ~100ft from one of the creators of tcsh so I definitely should have known better. I've updated to reflect your info. – metaperture Jul 29 '14 at 20:05
  • Well, cmd.exe is meant to be a superset of DOS command.com, which is a clone of the CP/M CCP with some minor changes, and I'll bet someone in your office at least has vague recollections of that. :) – abarnert Jul 29 '14 at 21:44
  • this is really good but it does not print on terminal. Can we both print on txt and terminal? – le4m Apr 13 '21 at 15:43
  • 1
    @jachilles added! – metaperture Apr 20 '21 at 13:23
  • Any way to append to the same file? – hafiz031 Jul 20 '21 at 20:46
  • 1
    @hafiz031 Use `>>` (sh append operator) instead of `>` in the first example. – metaperture Jul 21 '21 at 07:45
24

A quick and dirty hack to do this within the script is to direct the screen output to a file:

import sys 

stdoutOrigin=sys.stdout 
sys.stdout = open("log.txt", "w")

and then reverting back to outputting to screen at the end of your code:

sys.stdout.close()
sys.stdout=stdoutOrigin

This should work for a simple code, but for a complex code there are other more formal ways of doing it such as using Python logging.

ZZZ
  • 704
  • 9
  • 18
21

Let me summarize all the answers and add some more.

  • To write to a file from within your script, user file I/O tools that are provided by Python (this is the f=open('file.txt', 'w') stuff.

  • If don't want to modify your program, you can use stream redirection (both on windows and on Unix-like systems). This is the python myscript > output.txt stuff.

  • If you want to see the output both on your screen and in a log file, and if you are on Unix, and you don't want to modify your program, you may use the tee command (windows version also exists, but I have never used it)

  • Even better way to send the desired output to screen, file, e-mail, twitter, whatever is to use the logging module. The learning curve here is the steepest among all the options, but in the long run it will pay for itself.
Boris Gorelik
  • 29,945
  • 39
  • 128
  • 170
6

What you're asking for isn't impossible, but it's probably not what you actually want.

Instead of trying to save the screen output to a file, just write the output to a file instead of to the screen.

Like this:

with open('outfile.txt', 'w') as outfile:
    print >>outfile, 'Data collected on:', input['header']['timestamp'].date()

Just add that >>outfile into all your print statements, and make sure everything is indented under that with statement.


More generally, it's better to use string formatting rather than magic print commas, which means you can use the write function instead. For example:

outfile.write('Data collected on: {}'.format(input['header']['timestamp'].date()))

But if print is already doing what you want as far as formatting goes, you can stick with it for now.


What if you've got some Python script someone else wrote (or, worse, a compiled C program that you don't have the source to) and can't make this change? Then the answer is to wrap it in another script that captures its output, with the subprocess module. Again, you probably don't want that, but if you do:

output = subprocess.check_output([sys.executable, './otherscript.py'])
with open('outfile.txt', 'wb') as outfile:
    outfile.write(output)
abarnert
  • 354,177
  • 51
  • 601
  • 671
4

You would probably want this. Simplest solution would be

Create file first.

open file via

f = open('<filename>', 'w')

or

f = open('<filename>', 'a')

in case you want to append to file

Now, write to the same file via

f.write(<text to be written>)

Close the file after you are done using it

#good pracitice
f.close()
apsdehal
  • 845
  • 2
  • 10
  • 27
4

Here's a really simple way in python 3+:

f = open('filename.txt', 'w')
print('something', file = f)

^ found that from this answer: https://stackoverflow.com/a/4110906/6794367

Matt
  • 460
  • 6
  • 9
3

This is very simple, just make use of this example

import sys
with open("test.txt", 'w') as sys.stdout:
    print("hello")
DBat
  • 588
  • 2
  • 11
Fidelmak
  • 31
  • 2
0
python script_name.py > saveit.txt

Because this scheme uses shell command lines to start Python programs, all the usual shell syntax applies. For instance, By this, we can route the printed output of a Python script to a file to save it.

Ravi
  • 2,778
  • 2
  • 20
  • 32
0

I found a quick way for this:

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

def oprint(message):
    print(message)
    global log
    log.write(message)
    return()

code ...

log.close()

Whenever you want to print something just use oprint rather than print.

Note1: In case you want to put the function oprint in a module then import it, use:

import builtins

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

Note2: what you pass to oprint should be a one string (so if you were using a comma in your print to separate multiple strings, you may replace it with +)

0

We can simply pass the output of python inbuilt print function to a file after opening the file with the append option by using just two lines of code:

with open('filename.txt', 'a') as file:
    print('\nThis printed data will store in a file', file=file)

Hope this may resolve the issue...

Note: this code works with python3 however, python2 is not being supported currently.

S Habeeb Ullah
  • 968
  • 10
  • 15
0
idx = 0
for wall in walls:
    np.savetxt("C:/Users/vimal/OneDrive/Desktop/documents-export-2021-06-11/wall/wall_"+str(idx)+".csv",
               wall, delimiter=",")
    idx += 1
VirtualScooter
  • 1,792
  • 3
  • 18
  • 28
Vims Rocz
  • 57
  • 8
0
class Logger:
    def __init__(self, application_log_file, init_text="Program started", print_with_time=True):
        import sys
        self.__output_num = 0
        self.origin = sys.stdout
        self.init_text = init_text
        self.__init = False
        self.print_with_time = print_with_time
        self.log_file = application_log_file
        self.data = ""
        self.last_time = 0
        sys.stdout = self
        sys.stderr = self

    def flush(self):
        if self.data == "\n":
            return
        sys.stdout = self.origin
        print(self.__create_log_text(self.data) if self.print_with_time else self.data)
        with open(self.log_file, "a", encoding="utf-8") as log:
            log.write(self.__create_log_text(self.data))
        self.data = ""
        sys.stdout = self

    def __create_log_text(self, string: str):
        if self.last_time == str(datetime.datetime.today())[:-7]:
            return string
        self.last_time = str(datetime.datetime.today())[:-7]
        if not self.__init:
            self.__init = True
            return str(datetime.datetime.today())[:-7] + " | " + f"{self.init_text}\n"
        return str(datetime.datetime.today())[:-7] + " | " + string

    def write(self, data):
        self.data += data