ver sirven sintaxis que para ejemplos contenido comandos comando basicos archivo linux bash unix text

sirven - comandos linux terminal



¿Comando rápido de Unix para mostrar líneas específicas en el medio de un archivo? (17)

Estoy intentando depurar un problema con un servidor y mi único archivo de registro es un archivo de registro de 20GB (¡sin marcas de tiempo ni siquiera! ¿Por qué la gente usa System.out.println() como registro? ¿En producción ?!)

Usando grep, encontré un área del archivo que me gustaría ver, línea 347340107.

Aparte de hacer algo como

head -<$LINENUM + 10> filename | tail -20

... que requeriría que la head lea los primeros 347 millones de líneas del archivo de registro, ¿hay un comando rápido y sencillo que pueda volcar las líneas 347340100 - 347340200 (por ejemplo) a la consola?

actualización Olvidé totalmente que grep puede imprimir el contexto alrededor de un partido ... esto funciona bien. ¡Gracias!


Con sed -e ''1,N d; M q'' sed -e ''1,N d; M q'' imprimirá las líneas N + 1 a M. Esto es probablemente un poco mejor que grep -C ya que no intenta hacer coincidir las líneas con un patrón.


Encontré otras dos solutions si conoce el número de línea pero nada más (no es posible grep):

Suponiendo que necesita líneas de 20 a 40,

sed -n ''20,40p;41q'' file_name

o

awk ''FNR>=20 && FNR<=40'' file_name


Fácil con Perl! Si desea obtener la línea 1, 3 y 5 de un archivo, diga / etc / passwd:

perl -e ''while(<>){if(++$l~~[1,3,5]){print}}'' < /etc/passwd


Getck

ack --lines = nombre de archivo de inicio


Me sorprende que solo otra respuesta (de Ramana Reddy) sugiriera agregar números de línea a la salida. Lo siguiente busca el número de línea requerido y colorea la salida.

file=FILE lineno=LINENO wb="107"; bf="30;1"; rb="101"; yb="103" cat -n ${file} | { GREP_COLORS="se=${wb};${bf}:cx=${wb};${bf}:ms=${rb};${bf}:sl=${yb};${bf}" grep --color -C 10 "^[[:space:]]//+${lineno}[[:space:]]"; }


No, no, los archivos no son direccionables por línea.

No hay una forma constante de encontrar el inicio de la línea n en un archivo de texto. Debe transmitir el archivo y contar las nuevas líneas.

Use la herramienta más simple / más rápida que tenga para hacer el trabajo. Para mí, usar head tiene mucho más sentido que grep , ya que este último es mucho más complicado. No digo " grep is slow", realmente no lo es, pero me sorprendería que sea más rápido que la head en este caso. Eso sería un error en la head , básicamente.


Para mostrar una línea desde un <textfile> por su <line#> , simplemente haga esto:

perl -wne ''print if $. == <line#>'' <textfile>

Si quieres una forma más poderosa de mostrar un rango de líneas con expresiones regulares, no diré por qué grep es una mala idea para hacer esto, debería ser bastante obvio, esta simple expresión te mostrará tu rango en una single pass que es lo que desea cuando se trata de archivos de texto ~ 20GB:

perl -wne ''print if m/<regex1>/ .. m/<regex2>/'' <filename>

(consejo: si su expresión regular tiene / en ella, use algo como m!<regex>!

Esto imprimirá <filename> comenzando con la línea que coincide con <regex1> hasta (e incluyendo) la línea que coincide con <regex2> .

No hace falta un asistente para ver cómo algunos ajustes pueden hacerlo aún más poderoso.

Lo último: Perl, dado que es un lenguaje maduro, tiene muchas mejoras ocultas para favorecer la velocidad y el rendimiento. Con esto en mente, lo convierte en la opción obvia para una operación de este tipo, ya que se desarrolló originalmente para manejar archivos de registro de gran tamaño, texto, bases de datos, etc.


Prefiero ir a less y

  • escribiendo 5 0 % para ir a la mitad del archivo,
  • 43210 G para ir a la línea 43210
  • :43210 para hacer lo mismo

Y cosas como esa.

Aún mejor: presione v para comenzar a editar (en vim, por supuesto!), En esa ubicación. ¡Ahora, tenga en cuenta que vim tiene las mismas ataduras de teclas!


Primero dividí el archivo en algunos más pequeños como este

$ split --lines=50000 /path/to/large/file /path/to/output/file/prefix

y luego grep en los archivos resultantes.


Puede usar el comando ex , un editor de Unix estándar (parte de Vim ahora), por ejemplo

  • mostrar una sola línea (por ejemplo, 2º):

    ex +2p -scq file.txt

    sintaxis sed correspondiente: sed -n ''2p'' file.txt

  • rango de líneas (por ejemplo, 2-5 líneas):

    ex +2,5p -scq file.txt

    sintaxis sed: sed -n ''2,5p'' file.txt

  • desde la línea dada hasta el final (por ejemplo, desde el 5 hasta el final del archivo):

    ex +5,p -scq file.txt

    sintaxis sed: sed -n ''2,$p'' file.txt

  • rangos de línea múltiple (por ejemplo, 2-4 y 6-8 líneas):

    ex +2,4p +6,8p -scq file.txt

    sintaxis sed: sed -n ''2,4p;6,8p'' file.txt

Los comandos anteriores se pueden probar con el siguiente archivo de prueba:

seq 1 20 > file.txt

Explicación:

  • + o -c seguido del comando - ejecuta el comando (vi / vim) después de leer el archivo,
  • -s - modo silencioso, también utiliza el terminal actual como salida predeterminada,
  • q seguido de -c es el comando para salir del editor ( ! añada ! a la fuerza, por ejemplo, -scq! ).

Puedes probar este comando:

egrep -n "*" <filename> | egrep "<line number>"


Qué pasa:

tail -n +347340107 filename | head -n 100

No lo probé, pero creo que eso funcionaría.


Sobre la base de la respuesta de Sklivvz, aquí hay una buena función que se puede poner en un archivo .bash_aliases . Es eficiente en archivos grandes al imprimir cosas desde la parte frontal del archivo.

function middle() { startidx=$1 len=$2 endidx=$(($startidx+$len)) filename=$3 awk "FNR>=${startidx} && FNR<=${endidx} { print NR/" /"/$0 }; FNR>${endidx} { print /"END HERE/"; exit }" $filename }


Utilizar

x=`cat -n <file> | grep <match> | awk ''{print $1}''`

Aquí obtendrá el número de línea donde ocurrió la coincidencia.

Ahora puede usar el siguiente comando para imprimir 100 líneas

awk -v var="$x" ''NR>=var && NR<=var+100{print}'' <file>

o puedes usar "sed" también

sed -n "${x},${x+100}p" <file>


con GNU-grep, podrías decir

grep --context=10 ...


sed necesitará leer los datos también para contar las líneas. La única forma en que un atajo sería posible sería tener contexto / orden en el archivo para operar. Por ejemplo, si había líneas de registro precedidas por una fecha / hora de ancho fijo, etc., podría usar la utilidad de búsqueda Unix para realizar búsquedas binarias a través de los archivos para fechas / horas particulares.


# print line number 52 sed -n ''52p'' # method 1 sed ''52!d'' # method 2 sed ''52q;d'' # method 3, efficient on large files

método 3 eficiente en archivos grandes

forma más rápida de mostrar líneas específicas