2012-05-08 12 views
26

C'è un modo per farlo? Dire che ho un file che è una lista di nomi che va come questo:Inserisci riga a metà del file con Python?

  1. Alfred
  2. Bill
  3. Donald

Come potrei inserire il terzo nome, "Charlie", alla linea x (in questo caso 3) e manda automaticamente tutti gli altri in basso di una riga? Ho visto altre domande come questa, ma non hanno avuto risposte utili. Può essere fatto, preferibilmente con un metodo o un ciclo?

+0

Dubito che non avresti trovato una soluzione a questo con alcune ricerche di base. Sei sicuro di averlo fatto? –

+2

@AbhranilDas grazie al buon testo di tkbx ho trovato subito questa risposta! – dmeu

+0

correlati: [Come si scrive al centro di un file di testo durante la lettura dei suoi contenuti?] (Http://stackoverflow.com/q/16556944/4279) – jfs

risposta

39

Questo è un modo per fare il trucco.

f = open("path_to_file", "r") 
contents = f.readlines() 
f.close() 

contents.insert(index, value) 

f = open("path_to_file", "w") 
contents = "".join(contents) 
f.write(contents) 
f.close() 

"indice" e "valore" sono la linea e il valore della vostra scelta, le linee a partire da 0.

+4

Questo è probabilmente un po' più pulito della mia risposta, ma puoi evitare di aprire e chiudere il file due volte. – jordanm

+4

Non sarebbe più semplice usare 'f.writelines (contents)' invece di unirsi a te stesso? – zekel

+0

contents.insert (x, y) Mi piace questo, semplice –

2
  1. analizzare il file in una lista Python usando file.readlines() o file.read().split('\n')
  2. Identificare la posizione in cui è necessario inserire una nuova linea, in base ai criteri.
  3. Inserire un nuovo elemento dell'elenco utilizzando list.insert().
  4. Scrivi il risultato nel file.
+3

Solo una nota, 'file.read.split ('\ n ') 'dovrebbe essere' file.read(). split (' \ n ') ' – Harry

5

Si può solo leggere i dati in una lista e inserire il nuovo record in cui si desidera.

names = [] 
with open('names.txt', 'r+') as fd: 
    for line in fd: 
     names.append(line.split(' ')[-1].strip()) 

    names.insert(2, "Charlie") # element 2 will be 3. in your list 
    fd.seek(0) 
    fd.truncate() 

    for i in xrange(len(names)): 
     fd.write("%d. %s\n" %(i + 1, names[i])) 
4

Non ci farai vedere ciò che l'uscita dovrebbe essere simile, in modo da una possibile interpretazione è che si vuole questo come l'output:

  1. Alfred
  2. Bill
  3. Charlie
  4. Donald

(Inserisci Charlie, quindi aggiungi 1 a tutte le linee successive) Ecco una possibile soluzione:.

def insert_line(input_stream, pos, new_name, output_stream): 
    inserted = False 
    for line in input_stream: 
    number, name = parse_line(line) 
    if number == pos: 
     print >> output_stream, format_line(number, new_name) 
     inserted = True 
    print >> output_stream, format_line(number if not inserted else (number + 1), name) 

def parse_line(line): 
    number_str, name = line.strip().split() 
    return (get_number(number_str), name) 

def get_number(number_str): 
    return int(number_str.split('.')[0]) 

def format_line(number, name): 
    return add_dot(number) + ' ' + name 

def add_dot(number): 
    return str(number) + '.' 

input_stream = open('input.txt', 'r') 
output_stream = open('output.txt', 'w') 

insert_line(input_stream, 3, 'Charlie', output_stream) 

input_stream.close() 
output_stream.close() 
11

Se si desidera cercare un file per una stringa e aggiungere un nuovo testo alla riga successiva, uno degli eleganti modi per farlo è il seguente:

import fileinput 
for line in fileinput.FileInput(file_path,inplace=1): 
    if "TEXT_TO_SEARCH" in line: 
     line=line.replace(line,line+"NEW_TEXT") 
    print line, 
+4

Su python3, 'print (line, end = '')' è utile per non inserire linebreak aggiuntivi tra le righe. –

1

C'è una combinazione di tecniche che ho trovato utile per risolvere questo problema:

with open(file, 'r+') as fd: 
    contents = fd.readlines() 
    contents.insert(index, new_string) # new_string should end in a newline 
    fd.seek(0) # readlines consumes the iterator, so we need to start over 
    fd.writelines(contents) # No need to truncate as we are increasing filesize 

nella nostra applicazione particolare, abbiamo voluto aggiungere un commento dopo una certa stringa:

with open(file, 'r+') as fd: 
    contents = fd.readlines() 
    if match_string in contents[-1]: # Handle last line to prevent IndexError 
     contents.append(insert_string) 
    else: 
     for index, line in enumerate(contents): 
      if match_string in line and insert_string not in contents[index + 1]: 
       contents.insert(index + 1, insert_string) 
       break 
    fd.seek(0) 
    fd.writelines(contents) 

Se si vuole inserire la stringa dopo ogni istanza della partita, invece che solo il primo, togliere la else: (e correttamente Unindent) e il break.

Si noti inoltre che il and insert_string not in contents[index + 1]: impedisce di aggiungere più di una copia dopo il match_string, quindi è possibile eseguire più volte.

Problemi correlati