2012-05-30 14 views
6

Ho il seguente codice, che modifica ogni riga del file test.tex effettuando una sostituzione di espressioni regolari.Python scrive su file usando stdout e fileinput

import re 
import fileinput 

regex=re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)') 

for line in fileinput.input('test.tex',inplace=1): 
    print regex.sub(r'\3\2\1\4\5',line), 

L'unico problema è che io voglio solo la sostituzione di applicare ad alcune righe nel file, e non c'è modo di definire un modello per selezionare le linee corrette. Quindi, voglio visualizzare ogni riga e chiedere all'utente nella riga di comando, chiedendo se effettuare la sostituzione sulla linea corrente. Se l'utente inserisce "y", viene effettuata la sostituzione. Se l'utente non inserisce semplicemente nulla, la sostituzione è non effettuata.

Il problema, ovviamente, è che utilizzando il codice inplace=1 ho effettivamente reindirizzato lo stdout al file aperto. Quindi non c'è modo di mostrare l'output (ad esempio chiedendo se effettuare la sostituzione) alla riga di comando che non viene inviata al file.

Qualche idea?

+2

Usa stderr ..... –

+0

'fileinput' non è lo strumento giusto per questo lavoro. Basta usare un modello standard di lettura-modifica-scrittura –

+0

@EliBendersky puoi indicarmi un esempio di come si parla? Scusa, sono molto nuovo in Python. – synaptik

risposta

3

Il modulo di input del file è davvero per gestire più di un file di input. Puoi invece usare la normale funzione open().

Qualcosa di simile dovrebbe funzionare.

leggendo il file quindi resettare il puntatore con seek(), siamo in grado di sovrascrivere il file invece di aggiungere fino alla fine, e quindi modificare il file sul posto

import re 

regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)') 

with open('test.tex', 'r+') as f: 
    old = f.readlines() # Pull the file contents to a list 
    f.seek(0) # Jump to start, so we overwrite instead of appending 
    for line in old: 
     s = raw_input(line) 
     if s == 'y': 
      f.write(regex.sub(r'\3\2\1\4\5',line)) 
     else: 
      f.write(line) 

http://docs.python.org/tutorial/inputoutput.html

+2

Ovviamente, se si dispone di un file di grandi dimensioni che è troppo grande per essere caricato nella memoria, è possibile leggere una riga alla volta e scrivere invece su un file temporaneo. –

+0

Grazie mille! :) – synaptik

0

Based sull'aiuto fornito a tutti, ecco cosa ho finito con:

#!/usr/bin/python 

import re 
import sys 
import os 

# regular expression 
regex = re.compile(r'^([^&]*)(&)([^&]*)(&)([^&]*)') 

# name of input and output files 
if len(sys.argv)==1: 
    print 'No file specified. Exiting.' 
    sys.exit() 
ifilename = sys.argv[1] 
ofilename = ifilename+'.MODIFIED' 

# read input file 
ifile = open(ifilename) 
lines = ifile.readlines() 

ofile = open(ofilename,'w') 

# prompt to make substitutions wherever a regex match occurs 
for line in lines: 
    match = regex.search(line)  
    if match is not None: 
     print '' 
     print '***CANDIDATE FOR SUBSTITUTION***' 
     print '--: '+line, 
     print '++: '+regex.sub(r'\3\2\1\4\5',line), 
     print '********************************' 
     input = raw_input('Make subsitution (enter y for yes)? ') 
     if input == 'y': 
      ofile.write(regex.sub(r'\3\2\1\4\5',line)) 
     else: 
      ofile.write(line) 
    else: 
     ofile.write(line) 

# replace original file with modified file 
os.remove(ifilename) 
os.rename(ofilename, ifilename) 

Grazie mille!

Problemi correlati