¿Puedo grep solo las primeras n líneas de un archivo?


126

Tengo archivos de registro muy largos, ¿es posible pedirle a grep que solo busque las primeras 10 líneas?

Respuestas:


175

La magia de las pipas;

head -10 log.txt | grep <whatever>

13
también puede canalizar una secuencia arbitraria a head:someCmd | head -10
Stuart Nelson,

1
El cabezal está predeterminado para imprimir las primeras 10 líneas a la salida estándar, por lo que esto es válido para 10 líneashead log.txt | grep <whatever>
Zlemini

55
¿Hay alguna manera de hacer esto cuando se usa la -lopción de grep ? Me gustaría enumerar todos los archivos que son los primeros 5 caracteres RIFFD.
James M. Lay

49

Para las personas que encuentran esto en Google, necesitaba buscar las primeras nlíneas de varios archivos, pero solo imprimir los nombres de archivo coincidentes. solía

 gawk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' filenames

El FNR..nextfiledeja de procesar un archivo una vez que se han visto 10 líneas. Los //..{}grabados el nombre de archivo y se mueve sobre cada vez que el primer partido en una determinada muestra de archivo de hasta. Para citar los nombres de archivo en beneficio de otros programas, use

 gawk 'FNR>10 {nextfile} /pattern/ { print "\"" FILENAME "\"" ; nextfile }' filenames

9
Fui una de esas personas que encontró esto en Google. ¡Gracias!
Floris

para mí, este código imprimió la ruta completa del archivo. Que es exactamente lo que necesitaba. También FNR=1solo buscará la primera línea. ¡Gracias!
Brian W

2
Para hacer esto de forma recursiva en un directorio:find ./path -type -f -exec awk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' '{}' +
OrangeDog

1
Gracias @OrangeDog. Una pequeña corrección: debería ser-type f
David Siegal

26

O use awkpara un solo proceso sin |:

awk '/your_regexp/ && NR < 11' INPUTFILE

En cada línea, si your_regexpcoincide, y el número de registros (líneas) es inferior a 11, ejecuta la acción predeterminada (que es imprimir la línea de entrada).

O use sed:

sed -n '/your_regexp/p;10q' INPUTFILE 

Comprueba su expresión regular e imprime la línea ( -nsignifica que no imprime la entrada, que de lo contrario es la predeterminada), y se cierra justo después de la décima línea.


1
¿Por qué no renunciar el 10? (ver solución sed)
potong

awk '{ if ( NR <= 10 ) { if(index($0,"ab") > 0) { print $0; } } else { exit; } }' textfile-- Más rápido.

1
@potong tienes razón, corregido. @srikanthradix, aunque puede ser más rápido, su solución no es buscar expresiones regulares sino solo cadenas fijas. awk '{ if ( NR <= 10 ) { if( $0 ~ "YOUR_REGEXP") { print } } else { exit; } }' textfilehace.
Zsolt Botykai

44
Además, el estilo no lo es awkish. 2xifsy 1xelseen un comando que no necesita ninguna declaración de acción haría aho. weinberger y kernighan lloran ...
jaypal singh

1
Creo que, en lugar de NR, sería mejor usar FNR, porque si usa awk con varios archivos, FNR comienza desde 0 para cada archivo.
Vladyslav Savchenko

9

Tienes algunas opciones para usar programas junto con grep. Lo más simple en mi opinión es usar head:

head -n10 filename | grep ...

headgenerará las primeras 10 líneas (usando la -nopción), y luego puede canalizar esa salida grep.


66
Ni siquiera me di cuenta, todas las soluciones headque utilizamos aquí han utilizado -n 10 (incluyéndome a mí) sin darme cuenta de que, headpor defecto , solo muestra 10 líneas . :)
jaypal singh



3

La salida de head -10 filese puede canalizar greppara lograr esto:

head -10 file | grep 

Usando Perl:

perl -ne 'last if $. > 10; print if /pattern/' file

3
head -10 log.txt | grep -A 2 -B 2 pattern_to_search

-A 2: imprime dos líneas antes del patrón.

-B 2: imprime dos líneas después del patrón.

head -10 log.txt # read the first 10 lines of the file.

1
Si -C 2-A 2 -B 2
mal

3
grep -m6 "string" cov.txt

Esto busca solo las primeras 6 líneas para string


3
No, esto le dará las primeras 6 apariciones de "cadena" en todo el archivo cov.txt
franzisk

2

Una extensión de la respuesta de Joachim Isaksson: Muy a menudo necesito algo del medio de un archivo largo, por ejemplo, las líneas 5001 a 5020, en cuyo caso se puede combinar headcon tail:

head -5020 file.txt | tail -20 | grep x

Esto obtiene las primeras 5020 líneas, luego muestra solo las últimas 20 de esas, luego canaliza todo a grep.

(Editado: error de poste de la cerca en mis números de ejemplo, tubería agregada a grep)


1

grep -A 10 <Patrón>

Esto es para tomar el patrón y las siguientes 10 líneas después del patrón. Esto funcionaría bien solo para un patrón conocido, si no tiene un patrón conocido use las sugerencias de "cabeza".


1
Aunque podría ser correcto. agregue más descripción de la pregunta para que la respuesta sea más completa.
Pramod S. Nikam

3
Esto responde una pregunta completamente diferente y no es útil en este contexto.
Pre101

-1

Tuve un problema similar y todo el problema anterior no lo resuelve por completo. También estoy interesado en obtener el nombre del archivo que contiene las líneas coincidentes. Mi solución:

ls |parallel --gnu 'cat <(echo {}) <(head {})|grep -B1 -m1 -P "^>.*F3$"'

NB: El patrón en mi caso siempre coincide con la primera línea.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.