En esta respuesta ( ¿Cómo puedo eliminar la primera línea de un archivo con sed? ) Hay dos formas de eliminar el primer registro en un archivo:
sed '1d' $file >> headerless.txt
** ---------------- O ---------------- **
tail -n +2 $file >> headerless.txt
Personalmente, creo que la tail
opción es cosméticamente más agradable y más legible, pero probablemente porque estoy desafiada.
¿Qué método es el más rápido?
sed
es más portátil: "+2"tail
funciona bien en Ubuntu, que usa GNUtail
, pero no funcionará en BSDtail
.tail
falta de compatibilidad multiplataforma.-n
opción y usaba la sintaxistail +2 $file
. Ver freebsd.org/cgi/… Es posible que estuvieras pensando en eso en lugar de uno de los BSD modernos.Respuestas:
Rendimiento de
sed
vs.tail
para eliminar la primera línea de un archivoTL; DR
sed
es muy potente y versátil, pero esto es lo que lo hace lento, especialmente para archivos grandes con muchas líneas.tail
hace solo una cosa simple, pero esa lo hace bien y rápido, incluso para archivos más grandes con muchas líneas.Para archivos pequeños y medianos,
sed
ytail
tienen un rendimiento similar rápido (o lento, según sus expectativas). Sin embargo, para archivos de entrada más grandes (varios MB), la diferencia de rendimiento crece significativamente (un orden de magnitud para archivos en el rango de cientos de MB), con untail
rendimiento claramente superiorsed
.Experimentar
Preparaciones generales:
Nuestros comandos para analizar son:
Tenga en cuenta que estoy canalizando la salida
/dev/null
cada vez para eliminar la salida del terminal o las escrituras de archivos como cuello de botella de rendimiento.Configuremos un disco RAM para eliminar la E / S del disco como posible cuello de botella. Personalmente tengo un
tmpfs
montado en,/tmp
así que simplemente coloqué mitestfile
allí para este experimento.Luego, una vez estoy creando un archivo de prueba aleatorio que contiene una cantidad específica de líneas
$numoflines
con longitud de línea aleatoria y datos aleatorios usando este comando (tenga en cuenta que definitivamente no es óptimo, se vuelve realmente lento para aproximadamente> 2M líneas, pero a quién le importa, no es el lo que estamos analizando):Oh, por cierto. mi computadora portátil de prueba ejecuta Ubuntu 16.04, 64 bits en una CPU Intel i5-6200U. Solo para comparar.
Tiempo de archivos grandes:
Configurar un gran
testfile
:Ejecutar el comando anterior
numoflines=10000000
produjo un archivo aleatorio que contiene 10 millones de líneas, ocupando un poco más de 600 MB; es bastante grande, pero comencemos con él, porque podemos:Realice la ejecución cronometrada con nuestro enorme
testfile
:Ahora hagamos una sola ejecución temporizada con ambos comandos primero para estimar con qué magnitudes estamos trabajando.
Ya vemos un resultado realmente claro para archivos grandes,
tail
es una magnitud más rápido quesed
. Pero solo por diversión y para estar seguros de que no hay efectos secundarios aleatorios que hagan una gran diferencia, hagámoslo 100 veces:La conclusión sigue siendo la misma,
sed
es ineficiente para eliminar la primera línea de un archivo grande,tail
debe usarse allí.Y sí, sé que las construcciones de bucle de Bash son lentas, pero solo estamos haciendo relativamente pocas iteraciones aquí y el tiempo que toma un bucle simple no es significativo en comparación con los tiempos de ejecución
sed
/ detail
todos modos.Sincronización de archivos pequeños:
Configurar un pequeño
testfile
:Ahora para completar, veamos el caso más común de que tiene un pequeño archivo de entrada en el rango de kB. Creemos un archivo de entrada aleatorio con
numoflines=100
este aspecto:Realice la ejecución cronometrada con nuestro pequeño
testfile
:Como podemos esperar que los tiempos para archivos tan pequeños estén en el rango de unos pocos milisegundos de la experiencia, hagamos 1000 iteraciones de inmediato:
Como puede ver, los tiempos son bastante similares, no hay mucho para interpretar o preguntarse. Para archivos pequeños, ambas herramientas son igualmente adecuadas.
fuente
awk
puede hacer esto. Mi pregunta original se basó en el enlace que encontré en primer lugar. Después de todo su arduo trabajo, por favor avise si debo eliminarawk
como candidato a solución y volver a enfocar el alcance del proyecto original de solosed
ytail
.awk 'NR > 1'
, curiosamente).Aquí hay otra alternativa, usando solo bash builtins y
cat
:$file
se redirige a la{ }
agrupación de comandos. Elread
simplemente lee y descarta la primera línea. Luego se canaliza el resto de la secuencia a lacat
que se escribe en el archivo de destino.En mi Ubuntu 16.04, el rendimiento de esto y la
tail
solución son muy similares. Creé un archivo de prueba grande conseq
:tail
solución:cat
/ solución de llave:Sin embargo, solo tengo una máquina virtual Ubuntu en este momento, y vi una variación significativa en los tiempos de ambos, aunque todos están en el mismo estadio.
fuente
tail
pero todavía creo que laread
opción es muy buena.Probar en mi sistema y anteponer cada comando con
time
, obtuve los siguientes resultados:sed:
y cola:
lo que sugiere que, en mi sistema al menos AMD FX 8250 con Ubuntu 16.04, la cola es significativamente más rápida. El archivo de prueba tenía 10,000 líneas con un tamaño de 540k. El archivo fue leído desde un disco duro.
fuente
sed
podría jugar un factor en este resultado, ese es el orden en el que los probó.sed
fue aproximadamente el doble de rápido.No hay una forma objetiva de decir cuál es mejor, porque
sed
ytail
no son las únicas cosas que se ejecutan en un sistema durante la ejecución del programa. Muchos factores, como la E / S de disco, la E / S de red, las interrupciones de la CPU para procesos de mayor prioridad, influyen en la rapidez con que se ejecutará su programa.Ambos están escritos en C, por lo que este no es un problema de lenguaje, sino más bien ambiental. Por ejemplo, tengo SSD y en mi sistema esto llevará tiempo en microsegundos, pero para el mismo archivo en el disco duro tomará más tiempo porque los HDD son significativamente más lentos. Entonces el hardware también juega un papel en esto.
Hay algunas cosas que es posible que desee tener en cuenta al considerar qué comando elegir:
sed
es editor de flujo para transformar texto.tail
es para generar líneas específicas de texto. Si desea lidiar con líneas y solo imprimirlas, usetail
. Si desea editar el texto, usesed
.tail
tiene una sintaxis mucho más simple quesed
, así que use lo que pueda leer usted mismo y lo que otros puedan leer.Otro factor importante es la cantidad de datos que está procesando. Los archivos pequeños no le darán ninguna diferencia de rendimiento. La imagen se pone interesante cuando se trata de archivos grandes. Con un BIGFILE.txt de 2 GB, podemos ver que
sed
tiene muchas más llamadas al sistema quetail
, y funciona considerablemente más lento.fuente
tail
mejor quesed
, úsalo. Yo personalmente usaríapython
oawk
más biensed
porque puede volverse complejo. Además, si le preocupa el rendimiento, seamos sinceros: aquí está viendo resultados en microsegundos. No sentirás la diferencia a menos que sea un archivo enorme en el rango de gigabytes que estás tratando de leerawk
respuesta también:) ... Mi pregunta se basó en otra AU Q&A (en el enlace) y allí nunca mencionaronawk
. Estoy de acuerdo en que la diferencia horaria es nominal en archivos pequeños. Solo estaba tratando de desarrollar algunos buenos hábitos.awk 'NR!=1' input_file.txt
. Me da el mismo resultado, alrededor de 150 milisegundos, el mismo número para ambostail
ysed
. Pero antes, estoy usando SSD, así que diría que lo que importa es el disco duro y la CPU, no el comando.sed
toman más de 3 minutos, mientras quetail
solo necesitan alrededor de 20 segundos. Eso no es que no era grande, sin embargo, en realidad, sin duda en el rango GB.La respuesta principal no tuvo en cuenta el disco haciendo
> /dev/null
si tiene un archivo grande y no desea crear un duplicado temporal en su disco, intente
vim -c
Editar: si el archivo es más grande que la memoria disponible
vim -c
no funciona, parece que no es lo suficientemente inteligente como para hacer una carga incremental del archivofuente
Otras respuestas muestran bien qué es mejor crear un nuevo archivo sin la primera línea. Sin embargo, si desea editar un archivo en lugar de crear un nuevo archivo, apuesto a
ed
que sería más rápido porque no debería crear un nuevo archivo en absoluto. Pero tienes que buscar cómo eliminar una líneaed
porque la usé solo una vez.fuente