2

Currently I have this piece of code for python 2.7:

h = 0
for line in fileinput.input('HISTORY',inplace=1):
    if line[0:2] == x:
            h = h + 1
            if h in AU:
                    line = line.replace(x,'AU')
    if 'timestep' in line:
        h = 0
        sys.stdout.write(('\r%s%% ') % format(((os.stat('HISTORY').st_size / os.stat('HISTORY.bak').st_size)*100),'.1f'))
    sys.stdout.write(line)

What I am having trouble with is the following line:

sys.stdout.write(('\r%s%% ') % format(((os.stat('HISTORY').st_size / os.stat('HISTORY.bak').st_size)*100),'.1f'))

I need this information to be outputted to the console ONLY and not into the HISTORY file.

kalk2
  • 23
  • 2
  • According to the [fileinput documentation](https://docs.python.org/2/library/fileinput.html) `Optional in-place filtering: if the keyword argument inplace=1 is passed to fileinput.input() or to the FileInput constructor, the file is moved to a backup file and standard output is directed to the input file`. Maybe removing `inplace=1` is what you want? – cod3monk3y Nov 13 '14 at 19:37
  • That would work, but I need information from the backup file itself (i.e. HISTORY.bak) – kalk2 Nov 13 '14 at 19:47
  • Specifying `inplace=1` will direct *any* stdout to the 'HISTORY' file, this includes `print` and `sys.stdout.write`. If you don't want to write to 'HISTORY' you'll have to remove `inplace=1`. You'll still be *reading* from that file. And you don't need it of you don't plan on writing back to it. – cod3monk3y Nov 13 '14 at 19:52
  • and 'sys.stdout.write(line)' needs to be written into the input file – kalk2 Nov 13 '14 at 19:52
  • Ah, okay! Since `fileinput` is just creating a temporary backup file when you use `inplace=1`, how about just creating a backup yourself, removing `inplace=1`, then re-creating the HISTORY file? `sys.stdout.write(line)` would be come `f.write(line)` and you could leave the other one in place? I'll post some code in an answer. – cod3monk3y Nov 13 '14 at 19:55

2 Answers2

1

This code creates a temporary copy of the input file, then scans this and rewrites the original file. It handles errors during processing the file so that the original data isn't lost during the re-write. It demonstrates how to write some data to stdout occasionally and other data back to the original file.

The temporary file creation was taken from this SO answer.

import fileinput
import os, shutil, tempfile

# create a copy of the source file into a system specified
# temporary directory. You could just put this in the original
# folder, if you wanted
def create_temp_copy(src_filename):
    temp_dir = tempfile.gettempdir()
    temp_path = os.path.join(temp_dir, 'temp-history.txt')
    shutil.copy2(src_filename,temp_path)
    return temp_path

# create a temporary copy of the input file
temp = create_temp_copy('HISTORY.txt')

# open up the input file for writing
dst = open('HISTORY.txt','w+')

for line in fileinput.input(temp):

    # Added a try/catch to handle errors during processing.
    # If this isn't present, any exceptions that are raised
    # during processing could cause unrecoverable loss of
    # the HISTORY file
    try:
        # some sort of replacement 
        if line.startswith('e'):
            line = line.strip() + '@\n' # notice the newline here

        # occasional status updates to stdout
        if '0' in line:
            print 'info:',line.strip() # notice the removal of the newline
    except:
        # when a problem occurs, just output a message
        print 'Error processing input file'

    finally:
        # re-write the original input file
        # even if there are exceptions
        dst.write(line)

# deletes the temporary file
os.remove(temp)

# close the original file
dst.close()
Community
  • 1
  • 1
cod3monk3y
  • 9,508
  • 6
  • 39
  • 54
  • Glad to help. Also, checkout [this variation on creating the temporary copy](http://stackoverflow.com/a/26935420/1174169), which returns a file-like object which is automatically deleted on close. That code will allow you to get rid of `fileinput.input` and `os.remove`. – cod3monk3y Nov 14 '14 at 17:23
0

If you only want the information to go to the console could you just use print instead?

ACV
  • 1,895
  • 1
  • 19
  • 28