Sustituir cadenas en un archivo muy grande

Sustituir cadenas en un archivo muy grande

Tengo una serie muy larga de URL sin carácter de separación, en el mismo formato que se muestra a continuación:

http://example.comhttp://example.nethttp://example.orghttp://etc...

Quiero que cada URL esté en una nueva línea. Intenté hacer esto reemplazando todas las instancias de "http://" con "\nhttp://" usando sed

sed 's_http://_\nhttp://_g' urls.txt

pero ocurre una falla de segmentación (violación de memoria). Sólo puedo suponer que el gran tamaño del archivo (más de 100 GB) está provocando que sed exceda algún límite.

Podría dividir el archivo en varios archivos más pequeños para procesarlos, pero todas las instancias de "http://" deberían mantenerse intactas.

¿Hay una mejor manera de hacer esto?

Respuesta1

Con awkpuedes evitar leer una gran cantidad de texto a la vez:

awk -vRS='http://' -vORS='\nhttp://' 1 urls.txt > urlsperline.txt

El éxito puede depender de la awkimplementación utilizada. Por ejemplo, gawkfunciona bien, pero mawkfalla.

Respuesta2

Esto hará el trabajo:

perl -pe 'BEGIN { $/ = "//" } s!(?=http://\z)!\n!' urls.txt

Configurando$/, Cambié la definición de una línea para que termine en //lugar de una nueva línea. Esto hace que Perl lea una URL a la vez. Es poco probable que una URL contenga //excepto después del esquema, pero está bien si lo contiene, la expresión regular evitará que agregue nuevas líneas falsas.

Si desea evitar agregar una línea en blanco antes de la primera URL:

perl -pe 'BEGIN { $/ = "//"; print scalar <> } s!(?=http://\z)!\n!' urls.txt

Puede intentar realizar una evaluación comparativa para ver si s!http://\z!\nhttp://!es más rápido. Son equivalentes. Tenga en cuenta que la /gbandera no es necesaria en la sustitución, porque sólo puede haber una coincidencia por "línea".

Respuesta3

  1. Cambie todas las apariciones de a :con una nueva línea para dividir el archivo.
  2. Reemplazar
    • httpal final de la línea con
    • una nueva línea seguida de http:y agregarle la siguiente línea
  3. Repita una vez, para que se actualicen las líneas pares e impares.

Estos pasos se parecen a:

tr ':' '\n' | sed -e '/http$/{N;s/http\n/\nhttp:/}' | sed -e '/http$/{N;s/http\n/\nhttp:/}'
  1. Compruebe si hay líneas que no comienzan con http://, imprima los números de línea. Esto solo ocurriría si : está en algún lugar de la URL que no sea después de http.

    grep -nv '^http://'

información relacionada