Digamos que tengo un archivo de texto enorme (> 2 GB) y solo quiero cat
las líneas X
a Y
(por ejemplo, 57890000 a 57890010).
Por lo que entiendo, puedo hacer esto canalizando head
en tail
o viceversa, es decir,
head -A /path/to/file | tail -B
o alternativamente
tail -C /path/to/file | head -D
donde A
,B
,C
y D
se puede calcular a partir del número de líneas en el archivo, X
y Y
.
Pero hay dos problemas con este enfoque:
- Tienes que calcular
A
,B
,C
yD
. - Los comandos podrían
pipe
unos a otros muchos más líneas de las que me interesa leer (por ejemplo, si solo estoy leyendo unas pocas líneas en medio de un archivo enorme)
¿Hay alguna manera de que el shell solo funcione y genere las líneas que quiero? (mientras proporciona solo X
y Y
)?
Respuesta aceptada:
Sugiero el sed
solución, pero en aras de la exhaustividad,
awk 'NR >= 57890000 && NR <= 57890010' /path/to/file
Para cortar después de la última línea:
awk 'NR < 57890000 { next } { print } NR == 57890010 { exit }' /path/to/file
Prueba de velocidad (aquí en macOS, YMMV en otros sistemas):
- Archivo de 100 000 000 líneas generado por
seq 100000000 > test.in
- Líneas de lectura 50 000 000-50 000 010
- Pruebas sin ningún orden en particular
real
tiempo según lo informado porbash
time
incorporado
4.373 4.418 4.395 tail -n+50000000 test.in | head -n10
5.210 5.179 6.181 sed -n '50000000,50000010p;57890010q' test.in
5.525 5.475 5.488 head -n50000010 test.in | tail -n10
8.497 8.352 8.438 sed -n '50000000,50000010p' test.in
22.826 23.154 23.195 tail -n50000001 test.in | head -n10
25.694 25.908 27.638 ed -s test.in <<<"50000000,50000010p"
31.348 28.140 30.574 awk 'NR<57890000{next}1;NR==57890010{exit}' test.in
51.359 50.919 51.127 awk 'NR >= 57890000 && NR <= 57890010' test.in
Estos no son de ninguna manera puntos de referencia precisos, pero la diferencia es lo suficientemente clara y repetible* para dar una buena idea de la velocidad relativa de cada uno de estos comandos.
*:Excepto entre los dos primeros, sed -n p;q
y head|tail
, que parecen ser esencialmente iguales.