Múltiples acciones de búsqueda y reemplazo en un archivo de texto grande

11

Tengo un gran archivo de texto (aproximadamente 2 GB). Quiero hacer cinco acciones de búsqueda y reemplazo en el mismo archivo, y me gustaría hacerlo en un comando. Normalmente uso vim, abro el archivo, hago una acción de reemplazo, luego la siguiente, etc. Hay un problema, ya que noté que después de tres o cuatro búsquedas, vim falla debido a problemas de memoria.

Aquí hay dos ejemplos del comando que uso en Vim:

:%s/www\.abcdef/www.test.abcdef/g 
:%s/www\.klmnop/www.test.klmnop/g

¿Cuál es la mejor manera de manejar esto?

SPRBRN
fuente

Respuestas:

8

Yo usaría sed así:

sed -i "s/www\.abcdef/www.test.abcdef/g;s/www\.kmlnop/www.test.klmnop/g;" yourfile.txt

-ila opción representa el reemplazo "en el lugar". Puede indicarle a sed que cree una copia de seguridad de su archivo proporcionando una extensión a esta opción ( -i.bakhará una copia de seguridad de su archivo.txt como yourfile.txt.bak).

ssssteffff
fuente
¡Eso es rápido! No solo su respuesta ;-) sino que este script con 5 búsquedas y reemplazos es aproximadamente 10 veces más rápido que solo abrir el archivo en vim. Sin embargo, una cosa me confundió. Al principio pensé que el archivo .bak sería el archivo editado, pero por supuesto es el original.
SPRBRN
Diez acciones de búsqueda y reemplazo (con miles de visitas) en un archivo de 2GB de una vez, sin problemas de memoria. Menos de dos minutos en un escritorio promedio, ¡súper!
SPRBRN
Una pregunta ... Te escapas de los puntos en la cadena de reemplazo. ¿Es esto necesario?
SPRBRN
1
De nada @rxt :) En realidad, tienes razón, puedes usar puntos sin escape en la cadena de reemplazo sed. Lo intenté y funciona. Hay un buen hilo en Unix y Linux Stackexchange , y la respuesta aceptada no menciona los puntos como caracteres para escapar.
ssssteffff
2
@rxt dijiste reemplazar cadena, lo siento, no, no necesitas escapar de allí.
terdon
6

Si tiene muchos más patrones de búsqueda, puede guardarlos en un archivo y leer las sustituciones desde allí. Por ejemplo, digamos que estos son los contenidos de replacements.txt:

www\.abcdef www.test.abcdef 
www\.klmnop www.test.klmnop

Luego puede leer una lista de N reemplazos y reemplazarlos con esto:

while read from to; do
  sed -i "s/$from/$to/" infile.txt ; 
done < replacements.txt 

NOTAS

  • Esto supone que las cadenas de búsqueda no contienen espacios y que se deben escapar caracteres extraños replacements.txt.
  • Ejecutará uno sedpor reemplazo, lo que puede llevar un tiempo si tiene muchas operaciones de reemplazo.
  • Puede lidiar con un número arbitrario de reemplazos (miles o millones o lo que sea) siempre y cuando no le importe que llevará un poco más de tiempo.

Otra opción sería escribir lo anterior como un sedscript:

s/www\.abcdef/www\.test\.abcdef/g;
s/www\.kmlnop/www\.test\.klmnop/g;
s/aaaa/bbbb/g;
s/cccc/dddd/g;
s/eeee/ffff/g;

Luego puede ejecutar el script en su archivo y hará todos los reemplazos de una vez:

sed -f replace.sed infile.txt 
terdon
fuente
+1 para la ,, otra opción ''. ¡Podría ser útil tener los reemplazos almacenados en un archivo! (Espero recordar eso ...)
mpy
+1 para la "otra opción" también porque utiliza la funcionalidad nativa en lugar de un script personalizado, por lo que es más portátil / compartible
David Cook
@DavidCook gracias, pero no es más nativo o portátil que el otro. El primer enfoque es usar un bucle de shell POSIX, es exactamente tan portátil como el segundo. Será mucho más lento ya que utiliza un bucle de shell.
terdon
Tienes razón, lo que quise decir es que el formato del archivo de script sed es más portátil, porque utiliza la funcionalidad de sed incorporada en lugar de un script, que debería compartirse junto con el archivo replacements.txt. Sin embargo, ¡ambas son excelentes opciones!
David Cook