Supongo que todos conocen las útiles utilidades de línea cmd de Linux heady tail. headle permite imprimir las primeras X líneas de un archivo, tailhace lo mismo pero imprime el final del archivo. ¿Cuál es un buen comando para imprimir el medio de un archivo? algo así como middle --start 10000000 --count 20(imprima las líneas 10'000'000th hasta th 10'000'010th).
Estoy buscando algo que se ocupe de archivos grandes de manera eficiente. Lo intenté tail -n 10000000 | head 10y es horriblemente lento.

Respuestas:
Es posible que pueda acelerar eso un poco así:
En esos comandos, la opción
-nhacesedque "se suprima la impresión automática del espacio del patrón". Elpcomando "imprime [s] el espacio del patrón actual" y elqcomando "Salga [s] inmediatamente de la secuencia de comandos sed sin procesar más entradas ..." Las comillas son de lasedmanpágina .Por cierto, tu comando
comienza en la línea número diez millones desde el final del archivo, mientras que su comando "medio" parece comenzar en el número diez millones desde el principio, lo que sería equivalente a:
El problema es que para los archivos sin clasificar con líneas de longitud variable, cualquier proceso tendrá que pasar por el archivo contando nuevas líneas. No hay forma de atajar eso.
Sin embargo, si el archivo está ordenado (un archivo de registro con marcas de tiempo, por ejemplo) o tiene líneas de longitud fija, puede buscar en el archivo en función de una posición de byte. En el ejemplo del archivo de registro, podría hacer una búsqueda binaria varias veces como lo hace mi script de Python aquí *. En el caso del archivo de longitud de registro fija, es realmente fácil. Solo busca
linelength * linecountpersonajes en el archivo.* Sigo teniendo la intención de publicar otra actualización de ese script. Tal vez lo logre uno de estos días.
fuente
sedversión de Charlesmiddlefunción:middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }. Manejará múltiples argumentos de archivo, nombres de archivo con espacios, etc. Varios archivos se procesan juntos como si hubieran sido capturados de la misma manera que losedhace normalmente (de modo que el medio 1000 100 archivo1 archivo2 abarcaría el final del primer archivo hasta el principio del segundo si el primero tiene menos de 1100 líneas).middle startline count filenameo múltiples nombres de archivo:middle startline count file1 file2 file3o con redirección:middle startline count < filenameo en una tubería:some_command |conteo de línea de inicio medio` ocat file* | middle startline countDescubrí el siguiente uso de
sedEspero que sea útil para alguien!
fuente
sed -nargumento que lo hace bastante legible.extract_lines(){sed -n "$1,+$2p" <file>}que escribe en stdout.¡Es mi primera vez publicando aquí! De todos modos, este es fácil. Digamos que desea extraer la línea 8872 de su archivo llamado file.txt. Así es como lo haces:
cat -n file.txt | grep '^ * 8872'
Ahora la pregunta es encontrar 20 líneas después de esto. Para lograr esto haces
cat -n file.txt | grep -A 20 '^ * 8872'
Para ver líneas alrededor o antes, vea las banderas -B y -C en el manual grep.
fuente
cat -n file.txt | grep '^ *1'produce todas las líneas que tienen 1 en su lado derecho. ¿Cómo dar salida a la línea 1 con esta técnica? Sé que puedo encabezar -n 1 .... pero ¿cómo usar grep?La respuesta de Dennis es el camino a seguir. Pero usando solo cabeza y cola, debajo de bash:
middle () {head -n $ [$ 1 + $ 2] | cola -n $ 2; }Esto escanea las primeras líneas de $ 1 + $ 2 dos veces, por lo que es mucho peor que la respuesta de Dennis. Pero no necesitas recordar todas esas letras sed para usarlo ...
fuente
$[...]está en desuso, al menos en Bash. Además, te falta un parámetro de archivo.middle 10 10 < /var/log/auth.log.Use el siguiente comando para obtener el rango particular de líneas
Aquí debug.log es mi archivo que consta de una falta de líneas y solía imprimir las líneas del número de línea 1220974 al 1513793 en un archivo test.log. Espero que sea útil para capturar el rango de líneas.
fuente
Una versión ruby oneliner.
Puede ser útil para alguien. Las soluciones con 'sed' proporcionadas por Dennis y Dox son muy buenas, incluso porque parece más rápido.
fuente
Puedes usar 'nl'.
fuente
Por ejemplo, este awk imprimirá líneas entre 20 y 40
fuente
Si conoce los números de línea, digamos que desea obtener las líneas 1, 3 y 5 de un archivo, diga / etc / passwd:
fuente
Perl es rey:
fuente