Respuestas:
Con sed
, así:
sed '20,37d; 45d' < input.txt > output.txt
Si quisieras hacer esto en el lugar:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed 'hace esto creando un archivo temporal y enviando la salida a este archivo en lugar de a la salida estándar. ... No conozco ningún otro 'sed' pero la logística de actualizar "en el lugar" con un editor de flujo no "computa" :)
Si el archivo se adapta cómodamente a la memoria, también puede usarlo ed
.
Los comandos son bastante similares al sed
anterior con una diferencia notable : debe pasar la lista de números / rangos de línea que se eliminarán en orden descendente (desde el número / rango de línea más alto al más bajo). La razón es que cuando elimina / inserta / divide / une líneas con ed
, el búfer de texto se actualiza después de cada subcomando, por lo que si elimina algunas líneas, el resto de las siguientes líneas ya no estarán en la misma posición en el búfer cuando el Se ejecuta el siguiente subcomando. Entonces tienes que comenzar hacia atrás 1 . Edición en el
lugar :
ed -s in_file <<IN
45d
20,37d
w
q
IN
o
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
o
printf '%s\n' 45d 20,37d w q | ed -s in_file
Reemplace w
rite con ,p
rint si desea imprimir la salida resultante en lugar de escribir en el archivo. Si desea mantener el archivo original intacto y escribir en otro archivo, puede pasar el nuevo nombre de archivo al w
subcomando rite:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
A menos que esté dispuesto a calcular los nuevos números de línea después de cada d
elección, lo cual es bastante trivial para este caso particular (después de eliminar las líneas 20-37, es decir, 18 líneas, la línea 45 se convierte en la línea 27) para que pueda ejecutar:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Sin embargo, si tiene que eliminar múltiples números / rangos de línea, trabajar hacia atrás es obvio.
q
útil el comando al final? Supongo que existe de cualquier manera.
Simplemente léalo en la memoria, modifíquelo y luego vuelva a escribirlo. Puedes hacer algo como
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
Probado con un archivo de 5 líneas. Créditos a http://pleac.sourceforge.net/pleac_python/fileaccess.html , consulte la sección "Modificación de un archivo en su lugar sin un archivo temporal". Ver también /programming/125703/how-do-i-modify-a-text-file-in-python
Algunas notas:
Primero se puede truncar el archivo, luego escribir en él, en lugar de escribir, y luego truncar, como se indicó anteriormente. Sin embargo, no conozco una bandera de Python que permita leer, y luego escribir de forma truncada. Pero tal vez me falta algo, ya que el documento no está tan claro. Lo que me lleva a
A veces, los documentos de Python realmente apestan. Ver http://docs.python.org/library/functions.html#open
Los modos 'r +', 'w +' y 'a +' abren el archivo para actualizarlo (tenga en cuenta que 'w +' trunca el archivo).
¿Esto significa algo para ti? ¿Qué demonios está "abierto para actualizar"?
No sé si hacer esto en Python en lugar de algo unixy como el editor de flujo es mejor. Puede ser más portátil, pero no sé qué tan portátil es sed. Lo escribí así porque me siento más cómodo con la programación de bajo nivel que con las herramientas clásicas de Unix, que son buenas si hacen exactamente lo que quieres, pero (creo) generalmente son menos flexibles.
Este enfoque (manipular el archivo en la memoria) cambia la memoria por espacio en disco. Debería funcionar bien en máquinas con unos pocos GB de memoria para archivos de hasta unos cientos de Mb. Python no maneja cadenas de manera muy eficiente, por lo que cambiar a C / C ++, por ejemplo, aumentaría ligeramente el rendimiento y reduciría en gran medida el uso de la memoria.
Puede usar Vim en modo Ex:
ex -sc '20,37d|45d|x' file
d
borrar
x
guardar y cerrar