2010-03-04 15 views
8

¿Cómo puedo reemplazar todas las terminaciones de línea en archivo grande (> 100MB)? He tratado de hacerCómo reemplazar terminaciones de línea en VIM

:%s/\n/, /g

pero es demasiado lento.

+0

¿Por qué quieres hacer esto en VIM? Simplemente terminará con una línea larga que no puede leer (con ojos que sí lo son). Además, ¿qué terminaciones de línea existen: DOS, UNIX, MAC o una combinación? – Marichyasana

Respuesta

8

lo tanto, fui a través y probados/cronometrados algunas de las respuestas que fueron dadas por otras personas, más una respuesta de pitón propia. Aquí es lo que tengo:

tr:

> time tr "\n" "," <lines> line 
real 0m1.617s 
user 0m0.100s 
sys  0m1.520s 

pitón:

> time python -c 'import sys; print sys.stdin.read().replace("\n",", "),' <lines> line 
real 0m1.663s 
user 0m0.060s 
sys  0m1.610s 

awk:

> time awk '{printf("%s, ", $0)}' lines > line         
real 0m1.998s 
user 0m0.390s 
sys  0m1.600s 

Perl:

> time perl -e 'while (<>) { chomp; print "$_, " }' lines > line 
real 0m2.100s 
user 0m0.590s 
sys  0m1.510s 

sed:

> time sed 's/$/, /g' lines > line            
real 0m6.673s 
user 0m5.050s 
sys  0m1.630s 

Aquí está el archivo que he utilizado:

> ls -lh lines 
-rw-r--r-- 1 some one 101M 2010-03-04 19:54 lines 
> wc -l < lines 
1300000 
> head -n 3 < lines 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
> head -n 1 < lines | wc -c 
82 

Originalmente, los tiempos fueron tomadas en cygwin, que ahora se han adoptado con Ubuntu completamente actualizado 9.10. Además, el tamaño de los archivos de texto se aumentó a 100 megas, con líneas de 80 caracteres de ancho. Como puedes ver, cualquier cosa que no sea sed es una buena idea.

+2

soy muy sospechoso de sus resultados awk. vez que ordena un par de veces, no solo una vez. Python no debería ser más rápido que awk, teniendo en cuenta que lleva tiempo importar módulos y cosas – ghostdog74

+0

Se ejecutó varias veces, eso fue aproximadamente la media. Solo lo ejecuté unas 10 veces más, 1.7xx cada vez. Tal vez sería diferente si no estuviera usando cygwin awk. –

+0

@ ghostdog74 Tenías razón en sospechar mis resultados awk, lo volví a ejecutar en una caja de Linux real, y fue mucho más rápido. –

2

Utilice este script Perl para revisar su archivo; Sería más rápido que mantener todo en la memoria con VIM. Simplemente canalice la salida a un nuevo archivo.

#!/usr/local/bin/perl 

while (<>) { 
    $_ =~ s/\n/,/g; 
    print $_; 
} 
+0

Supongo que el intérprete de Perl no es lo suficientemente inteligente como para saber que en este caso '$ _' no puede tener una nueva línea, excepto para el último carácter -' chomp' es probablemente mucho más rápido. – Cascabel

+0

@Jefromi En mi prueba totalmente no científica, es aproximadamente 300 ms más rápido usar chomp en un archivo de 100 megas. –

0

¿Tienes que hacer esto en vim?

Hay una buena utilidad Unix que hace la traducción basada en caracteres. Se llama tr. Algunos reference.

En su caso sería:

 
tr "\n" "," < input_file > output_file 
+0

Esto es casi seguro más rápido que las soluciones que publiqué, pero desafortunadamente, sustituye "," en lugar de "," como solicitó el OP. No estoy seguro de que haya una manera de hacer eso con 'tr', ¿verdad? – Cascabel

+0

tr solo toma un solo carácter – ghostdog74

+0

No, no, no noté el espacio allí. Para poner en más de 1 personaje, uno podría usar sed como alguien publicado a continuación. – pajton

3

:%s/$/, / seguido de un :1,$j podría ser más rápido. De lo contrario, hacerlo de una utilidad externa:

perl -e 'while (<>) { chomp; print "$_, " }' input_file > output_file 

awk '{printf("%s, ", $0)}' input_file > output_file 

No sabe la parte superior de la cabeza que sería más rápido.

+0

'perl -ne 'chomp; imprimir "$ _," 'archivo'. '-n'" asume while loop " – ghostdog74

+0

Buena llamada en' -n'. – Cascabel

+0

@sparrkey, "perl se ejecutará más rápido" no está justificado. – ghostdog74

0
$ more file 
aaaa 
bbbb 
cccc 
dddd 
eeee 

$ awk 'NR>1{printf("%s, ", p)}{p=$0}END{print p}' file 
aaaa, bbbb, cccc, dddd, eeee 

$ sed -e :b -e '$!N;s/\n/, /;tb' file 
+0

¿Has probado tu comando sed? sed 'N; s/\ n /, /' archivo – sparkkkey

+0

no realmente. es un corte y pega de wiki, pero creo que wiki no se puede confiar a veces. – ghostdog74

0

La mejor herramienta es sed y puedes usarla con:! comando

a fin de utilizar :!sed -e 's/\n/,/g' % > %.tmp ; cat %.tmp > % ; rm %.tmp'

Es necesario crear un archivo tmp con el cambio antes de integrar en su archivo actual

+0

¿Has probado tu comando sed? – ghostdog74

+0

sí Lo pruebo antes de – shingara

Cuestiones relacionadas