2012-05-08 9 views
26

¿Hay alguna manera de hacerlo? Decir que tengo un archivo que es una lista de nombres que dice así:¿Insertar línea en medio del archivo con Python?

  1. Alfred
  2. Bill
  3. Donald

¿Cómo podría insertar el tercer nombre, "Charlie", en la línea x (en este caso 3), y enviar automáticamente a 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?

+0

Dudo que no encuentre una solución a esto con algunas investigaciones básicas. ¿Estás seguro de haber hecho eso? –

+2

@AbhranilDas gracias a la buena redacción de tkbx ¡Encontré inmediatamente esta respuesta! – dmeu

+0

relacionado: [¿Cómo escribo en medio de un archivo de texto mientras leo su contenido?] (Http://stackoverflow.com/q/16556944/4279) – jfs

Respuesta

39

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, líneas empezando por 0.

+4

Esto es probablemente un poco más limpio que mi respuesta, pero puede evitar abrir y cerrar el archivo dos veces. – jordanm

+4

¿No sería más simple usar 'f.writelines (contents)' en lugar de unirlo usted mismo? – zekel

+0

contents.insert (x, y) me gusta, simple –

2
  1. analizar el archivo en una lista de Python usando file.readlines() o file.read().split('\n')
  2. Identificar la posición en la que tiene que insertar una nueva línea, de acuerdo con sus criterios.
  3. Inserta un nuevo elemento de lista allí usando list.insert().
  4. Escriba el resultado en el archivo.
+3

Solo una nota, 'file.read.split ('\ n ') 'debe ser' file.read(). split (' \ n ') ' – Harry

5

Puede acaba de leer los datos en una lista e insertar el nuevo registro en el que desea.

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

Usted no nos muestran lo que la salida debe ser similar, por lo que una posible interpretación es que desea que esta como la salida:

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

(Insertar Charlie, luego agregar 1 a todas las líneas posteriores) 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() 
11

Si desea buscar un archivo para una subcadena y añadir un nuevo texto a la línea siguiente, una de las formas 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, 
+4

En python3, 'print (line, end = '')' es útil para no insertar linebreaks adicionales entre líneas. –

1

Hay una combinación de técnicas que he encontrado ú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, queríamos añadirlo despues de una determinada cadena:

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 se inserte la cadena después de cada instancia del partido, en lugar de sólo la primera, retirar el else: (y adecuadamente Unindent) y el break.

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

Cuestiones relacionadas