Posso grep apenas as primeiras n linhas de um arquivo?


126

Eu tenho arquivos de log muito longos, é possível pedir ao grep para pesquisar apenas as 10 primeiras linhas?

Respostas:


175

A magia dos canos;

head -10 log.txt | grep <whatever>

13
Você também pode canalizar um fluxo arbitrário head:someCmd | head -10
Stuart Nelson

1
Cabeça padrões para imprimir as primeiras 10 linhas de saída padrão, de modo que este é válido para 10 linhashead log.txt | grep <whatever>
Zlemini

5
Existe uma maneira de fazer isso ao usar a -lopção grep ? Eu gostaria de listar todos os arquivos com os 5 primeiros caracteres RIFFD.
James M. Lay

49

Para as pessoas que encontrarem isso no Google, eu precisava pesquisar as primeiras nlinhas de vários arquivos, mas imprimir apenas os nomes de arquivos correspondentes. eu usei

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

Para o FNR..nextfileprocessamento de um arquivo depois que 10 linhas são vistas. Ele //..{}imprime o nome do arquivo e segue sempre que a primeira correspondência em um determinado arquivo é exibida. Para citar os nomes de arquivos em benefício de outros programas, use

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

9
Eu fui uma dessas pessoas que encontrou isso no Google. Obrigado!
Floris

para mim, esse código imprimiu o caminho completo do arquivo. O que é exatamente o que eu precisava. Também FNR=1apenas pesquisará a 1ª linha. Obrigado!
Brian W

2
Para fazer isso recursivamente em um diretório:find ./path -type -f -exec awk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' '{}' +
OrangeDog 7/19/19

1
Obrigado @OrangeDog. Uma ligeira correção: deveria ser #-type f
David Siegal

26

Ou use awkpara um único processo sem |:

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

Em cada linha, se your_regexpcorresponder, e o número de registros (linhas) for menor que 11, ele executará a ação padrão (que está imprimindo a linha de entrada).

Ou use sed:

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

Verifica sua regexp e imprime a linha ( -nsignifica não imprimir a entrada, que é o padrão) e sai logo após a 10ª linha.


1
Por que não sair no dia 10? (ver solução sed)
Potong

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

1
@potong você está certo, corrigido. @srikanthradix, embora possa ser mais rápido, sua solução não está procurando regexps, mas apenas cadeias de caracteres fixas. awk '{ if ( NR <= 10 ) { if( $0 ~ "YOUR_REGEXP") { print } } else { exit; } }' textfilefaz.
Zsolt Botykai

4
Além disso, o estilo não é awkish. 2xifse 1xelseem um comando que não precisa de nenhuma declaração de ação faria aho. weinberger e kernighan cry ...
jaypal singh

1
Eu acho que, em vez de NR, seria melhor usar o FNR, porque se você usar o awk com vários arquivos, o FNR inicia a partir de 0 para cada arquivo.
Vladyslav Savchenko 04/10

9

Você tem algumas opções usando programas junto com grep. O mais simples na minha opinião é usar head:

head -n10 filename | grep ...

headproduzirá as 10 primeiras linhas (usando a -nopção) e você poderá canalizar essa saída para grep.


6
Eu nem percebi, todas as soluções aqui headusadas usaram -n 10 (inclusive eu) sem perceber que, headpor padrão, exibe apenas 10 linhas . :)
jaypal singh



3

A saída de head -10 filepode ser canalizada greppara fazer isso:

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 duas linhas antes do padrão.

-B 2: imprime duas linhas após o padrão.

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

1
Se bem me lembro, -C 2fará o mesmo que-A 2 -B 2
David LeBauer 24/01

3
grep -m6 "string" cov.txt

Ele procura apenas as 6 primeiras linhas para string


3
Não, isso fornecerá as 6 primeiras ocorrências de "string" em todo o arquivo cov.txt
franzisk

2

Uma extensão da resposta de Joachim Isaksson: Muitas vezes, preciso de algo do meio de um arquivo longo, por exemplo, linhas 5001 a 5020; nesse caso, você pode combinar headcom tail:

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

Isso obtém as primeiras 5020 linhas, depois mostra apenas as últimas 20 e, em seguida, canaliza tudo para grep.

(Editado: erro fencepost nos meus exemplos de números, adicionado pipe ao grep)


1

grep -A 10 <Padrão>

Isso é para pegar o padrão e as próximas 10 linhas após o padrão. Isso funcionaria bem apenas para um padrão conhecido, se você não tiver um padrão conhecido, use as sugestões "head".


1
Embora possa estar certo. adicione mais descrição da pergunta para tornar a resposta mais abrangente.
Pramod S. Nikam

3
Isso responde a uma pergunta completamente diferente e não é útil nesse contexto.
Pre101

-1

Eu tive um problema semelhante e todo o problema acima não resolve completamente. Também estou interessado em obter o nome do arquivo que contém as linhas correspondentes. Minha solução:

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

NB: O padrão no meu caso sempre corresponde à primeira linha.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.