¿Insertar línea en medio del archivo con Python?

¿Hay alguna forma de hacer esto? Digamos que tengo un archivo que es una lista de nombres que va así:

  1. Alfredo
  2. Cuenta
  3. Donald

¿Cómo podría insertar el tercer nombre, “Charlie”, en la línea x (en este caso 3), y enviar automáticamente todos los demás una línea? He visto otras preguntas como esta, pero no obtuvieron respuestas útiles. ¿Se puede hacer, preferiblemente con un método o un bucle?

Esta es una forma de hacer el truco.

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() 

“índice” y “valor” son la línea y el valor de su elección, las líneas que comienzan desde 0.

Si desea buscar una subcadena en un archivo y agregar un nuevo texto a la siguiente línea, una de las formas más elegantes de hacerlo es la siguiente:

 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, 

Solo puede leer los datos en una lista e insertar el nuevo registro donde desee.

 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])) 

No nos muestra cómo debería ser la salida, por lo que una posible interpretación es que desea esto como salida:

  1. Alfredo
  2. Cuenta
  3. Charlie
  4. Donald

(Inserte Charlie, luego agregue 1 a todas las líneas subsiguientes). Aquí hay una solución posible:

 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() 
  1. Analice el archivo en una lista de python usando file.readlines() o file.read().split('\n')
  2. Identifique la posición donde debe insertar una nueva línea, de acuerdo con sus criterios.
  3. Inserte un nuevo elemento de lista allí usando list.insert() .
  4. Escribe el resultado en el archivo.

Hay una combinación de técnicas que encontré útiles para resolver este 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 

En nuestra aplicación particular, quisimos agregarla después de una cadena determinada:

 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) 

Si desea que inserte la cadena después de cada instancia de la coincidencia, en lugar de solo la primera, elimine la else: (y, por lo tanto, uninente) y la break .

Tenga en cuenta también que and insert_string not in contents[index + 1]: evita que agregue más de una copia después de match_string , por lo que es seguro ejecutarla repetidamente.

Una forma simple pero no eficiente es leer todo el contenido, cambiarlo y luego reescribirlo:

 line_index = 3 lines = None with open('file.txt', 'r') as file_handler: lines = file_handler.readlines() lines.insert(line_index, 'Charlie') with open('file.txt', 'w') as file_handler: file_handler.writelines(lines)