Intento depurar un problema con un servidor y mi único archivo de registro es un archivo de registro de 20 GB (¡sin marcas de tiempo incluso! ¿Por qué la gente usa System.out.println()
como registro? ¿En producción?)
Usando grep, he encontrado un área del archivo que me gustaría ver, línea 347340107.
Aparte de hacer algo como
head -<$LINENUM + 10> filename | tail -20
... lo que requeriría head
leer las primeras 347 millones de líneas del archivo de registro, ¿hay un comando rápido y fácil que volcaría las líneas 347340100 - 347340200 (por ejemplo) a la consola?
actualización Olvidé por completo que grep puede imprimir el contexto alrededor de un partido ... esto funciona bien. ¡Gracias!
Respuestas:
con GNU-grep podrías decir
fuente
Encontré otras dos soluciones si conoces el número de línea pero nada más (no es posible grep):
Suponiendo que necesita las líneas 20 a 40,
o
fuente
41q
que abandone la línea41
.método 3 eficiente en archivos grandes
forma más rápida de mostrar líneas específicas
fuente
No, no existe, los archivos no son direccionables en línea.
No hay una forma de tiempo constante para encontrar el inicio de la línea n en un archivo de texto. Debe transmitir a través del archivo y contar nuevas líneas.
Use la herramienta más simple / rápida que tiene para hacer el trabajo. Para mí, usar
head
tiene mucho más sentido quegrep
, ya que este último es mucho más complicado. No estoy diciendo "grep
es lento", realmente no lo es, pero me sorprendería si fuera más rápido quehead
en este caso. Eso sería un errorhead
, básicamente.fuente
Qué pasa:
No lo probé, pero creo que funcionaría.
fuente
Prefiero solo entrar
less
y:43210
hacer lo mismoY cosas como esa.
Aún mejor: presione vpara comenzar a editar (¡en vim, por supuesto!), En esa ubicación. ¡Ahora, tenga en cuenta que
vim
tiene las mismas combinaciones de teclas!fuente
Primero dividí el archivo en unos pocos más pequeños como este
y luego grep en los archivos resultantes.
fuente
Puede usar el
ex
comando, un editor estándar de Unix (parte de Vim ahora), por ejemplomostrar una sola línea (por ejemplo, la segunda):
sintaxis de sed correspondiente:
sed -n '2p' file.txt
rango de líneas (por ejemplo, 2-5 líneas):
sintaxis sed:
sed -n '2,5p' file.txt
desde la línea dada hasta el final (por ejemplo, 5º al final del archivo):
sintaxis sed:
sed -n '2,$p' file.txt
múltiples rangos de línea (por ejemplo, 2-4 y 6-8 líneas):
sintaxis sed:
sed -n '2,4p;6,8p' file.txt
Los comandos anteriores se pueden probar con el siguiente archivo de prueba:
Explicación:
+
o-c
seguido del comando: ejecute 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 (agregar!
para hacer forzar el cierre, por ejemplo-scq!
).fuente
Si su número de línea es 100 para leer
fuente
Obtener
ack
Instalación de Ubuntu / Debian:
Entonces corre:
Ejemplo:
De
$ man ack
:fuente
--lines
parámetro se ha eliminado.sed también necesitará leer los datos para contar las líneas. La única forma en que sería posible un acceso directo sería que hubiera un contexto / orden en el archivo para operar. Por ejemplo, si hubiera líneas de registro antepuestas con una fecha / hora de ancho fijo, etc., podría usar la utilidad look unix para la búsqueda binaria a través de los archivos para fechas / horas particulares
fuente
Utilizar
Aquí obtendrá el número de línea donde ocurrió la coincidencia.
Ahora puede usar el siguiente comando para imprimir 100 líneas
o puedes usar "sed" también
fuente
Con esto
sed -e '1,N d; M q'
, imprimirá las líneas N + 1 a M. Esto probablemente sea un poco mejor,grep -C
ya que no intenta hacer coincidir las líneas con un patrón.fuente
-e
Es opcional aquí.Sobre la base de la respuesta de Sklivvz, aquí hay una buena función que uno puede poner en un
.bash_aliases
archivo. Es eficiente en archivos grandes cuando se imprimen cosas desde el frente del archivo.fuente
Para mostrar una línea desde a
<textfile>
por su<line#>
, simplemente haga esto:Si desea 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 le mostrará su rango en un pase único, que es lo que desea cuando se trata de archivos de texto de ~ 20 GB:
(consejo: si tu expresión regular tiene
/
, usa algo como en sum!<regex>!
lugar)Esto se imprimiría
<filename>
comenzando con la línea que coincide<regex1>
hasta (e incluyendo) la línea que coincide<regex2>
.No hace falta un asistente para ver cómo algunos ajustes pueden hacerlo aún más poderoso.
Lo último: perl, ya 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 grandes archivos de registro, texto, bases de datos, etc.
fuente
Puedes probar este comando:
fuente
Fácil con perl! Si desea obtener las líneas 1, 3 y 5 de un archivo, diga / etc / passwd:
fuente
Me sorprende que solo otra respuesta (de Ramana Reddy) sugiera agregar números de línea a la salida. Lo siguiente busca el número de línea requerido y colorea la salida.
fuente