Supongo que todos conocen las útiles utilidades de línea cmd de Linux head
y tail
. head
le permite imprimir las primeras X líneas de un archivo, tail
hace 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 10
y es horriblemente lento.
Respuestas:
Es posible que pueda acelerar eso un poco así:
En esos comandos, la opción
-n
hacesed
que "se suprima la impresión automática del espacio del patrón". Elp
comando "imprime [s] el espacio del patrón actual" y elq
comando "Salga [s] inmediatamente de la secuencia de comandos sed sin procesar más entradas ..." Las comillas son de lased
man
pá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 * linecount
personajes 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
sed
versión de Charlesmiddle
funció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 losed
hace 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 filename
o múltiples nombres de archivo:middle startline count file1 file2 file3
o con redirección:middle startline count < filename
o en una tubería:some_command |
conteo de línea de inicio medio` ocat file* | middle startline count
Descubrí el siguiente uso de
sed
Espero que sea útil para alguien!
fuente
sed -n
argumento 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:
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