¿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?

David LeBauer
fuente

Respuestas:

175

La magia de las pipas;

head -10 log.txt | grep <whatever>
Joachim Isaksson
fuente
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
cxw
fuente
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.

Zsolt Botykai
fuente
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.

Dan Fego
fuente
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
4
grep "pattern" <(head -n 10 filename)
jaypal singh
fuente
3

Puede usar la siguiente línea:

head -n 10 /path/to/file | grep [...]
Gustavo Straube
fuente
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
Alan Haggai Alavi
fuente
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.
vins
fuente
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

Dileepa Chandima
fuente
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)

RoG
fuente
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".

snowtop
fuente
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.

Shokrof
fuente