Puis-je grep uniquement les n premières lignes d'un fichier?

126

J'ai des fichiers journaux très longs, est-il possible de demander à grep de ne rechercher que les 10 premières lignes?

David LeBauer
la source

Réponses:

175

La magie des pipes;

head -10 log.txt | grep <whatever>
Joachim Isaksson
la source
13
vous pouvez également diriger un flux arbitraire vers head:someCmd | head -10
Stuart Nelson
1
Par défaut, Head imprime les 10 premières lignes sur la sortie standard, c'est donc valable pour 10 ligneshead log.txt | grep <whatever>
Zlemini
5
Existe-t-il un moyen de faire cela lors de l'utilisation de l' -loption grep ? Je voudrais lister tous les fichiers des 5 premiers caractères RIFFD.
James M. Lay
49

Pour les gens qui trouvent cela sur Google, j'avais besoin de rechercher les premières nlignes de plusieurs fichiers, mais de n'imprimer que les noms de fichiers correspondants. j'ai utilisé

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

L' FNR..nextfilearrêt de traiter un fichier une fois que 10 lignes ont été vues. Le //..{}imprime le nom du fichier et continue chaque fois que la première correspondance dans un fichier donné apparaît. Pour citer les noms de fichiers au profit d'autres programmes, utilisez

 gawk 'FNR>10 {nextfile} /pattern/ { print "\"" FILENAME "\"" ; nextfile }' filenames
cxw
la source
9
J'étais l'une de ces personnes qui ont trouvé ça sur Google. Merci!
Floris
pour moi, ce code a imprimé le chemin complet du fichier. C'est exactement ce dont j'avais besoin. FNR=1Recherche aussi simplement la 1ère ligne. Merci!
Brian W
2
Pour faire cela récursivement sur un répertoire:find ./path -type -f -exec awk 'FNR>10 {nextfile} /pattern/ { print FILENAME ; nextfile }' '{}' +
OrangeDog
1
Merci @OrangeDog. Une légère correction: devrait être-type f
David Siegal
26

Ou utiliser awkpour un seul processus sans |:

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

Sur chaque ligne, si your_regexpcorrespond et que le nombre d'enregistrements (lignes) est inférieur à 11, il exécute l'action par défaut (qui imprime la ligne d'entrée).

Ou utilisez sed:

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

Vérifie votre expression régulière et imprime la ligne ( -nsignifie ne pas imprimer l'entrée, qui est sinon la valeur par défaut), et se ferme juste après la 10e ligne.

Zsolt Botykai
la source
1
Pourquoi ne pas arrêter le 10? (voir solution sed)
potong
awk '{ if ( NR <= 10 ) { if(index($0,"ab") > 0) { print $0; } } else { exit; } }' textfile-- plus rapide.
1
@potong vous avez raison, corrigé. @srikanthradix bien que cela puisse être plus rapide, votre solution ne recherche pas les expressions rationnelles mais uniquement les chaînes fixes. awk '{ if ( NR <= 10 ) { if( $0 ~ "YOUR_REGEXP") { print } } else { exit; } }' textfileEst-ce que.
Zsolt Botykai
4
De plus, le style ne l'est pas awkish. 2xifset 1xelsedans une commande qui n'a besoin d'aucune instruction d'action ferait aho. weinberger et kernighan pleurent ...
jaypal singh
1
Je pense qu'au lieu de NR, il serait préférable d'utiliser FNR, car si vous utilisez awk avec plusieurs fichiers, FNR commence à 0 pour chaque fichier.
Vladyslav Savchenko
9

Vous avez quelques options en utilisant des programmes avec grep. Le plus simple à mon avis est d'utiliser head:

head -n10 filename | grep ...

headaffichera les 10 premières lignes (en utilisant l' -noption), puis vous pourrez diriger cette sortie vers grep.

Dan Fego
la source
6
Je ne me suis même pas rendu compte, toutes les solutions utilisant ici headont utilisé -n 10 (y compris moi) ne réalisant pas que headpar défaut affiche seulement 10 lignes . :)
jaypal singh
4
grep "pattern" <(head -n 10 filename)
jaypal singh
la source
3

Vous pouvez utiliser la ligne suivante:

head -n 10 /path/to/file | grep [...]
Gustavo Straube
la source
3

La sortie de head -10 filepeut être redirigée vers grepafin d'accomplir ceci:

head -10 file | grep 

Utilisation de Perl:

perl -ne 'last if $. > 10; print if /pattern/' file
Alan Haggai Alavi
la source
3
head -10 log.txt | grep -A 2 -B 2 pattern_to_search

-A 2: imprimez deux lignes avant le motif.

-B 2: imprimer deux lignes après le motif.

head -10 log.txt # read the first 10 lines of the file.
vins
la source
1
Si je me souviens bien, -C 2fera la même chose que-A 2 -B 2
David LeBauer le
3
grep -m6 "string" cov.txt

Cela recherche uniquement les 6 premières lignes pour string

Dileepa Chandima
la source
3
Non, cela vous donnera les 6 premières occurrences de "string" dans tout le fichier cov.txt
franzisk
2

Une extension de la réponse de Joachim Isaksson: J'ai souvent besoin de quelque chose au milieu d'un long fichier, par exemple les lignes 5001 à 5020, auquel cas vous pouvez combiner headavec tail:

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

Cela obtient les 5020 premières lignes, puis n'affiche que les 20 dernières de celles-ci, puis redirige tout vers grep.

(Modifié: erreur fencepost dans mes numéros d'exemple, ajout d'un tube à grep)

RoG
la source
1

grep -A 10 <Modèle>

Il s'agit de saisir le motif et les 10 lignes suivantes après le motif. Cela ne fonctionnerait bien que pour un modèle connu, si vous n'avez pas de modèle connu, utilisez les suggestions "head".

snowtop
la source
1
Bien que cela puisse convenir. ajoutez plus de description de la question pour rendre la réponse plus complète.
Pramod S.Nikam
3
Cela répond à une question complètement différente et n'est pas utile dans ce contexte.
Pré101
-1

J'ai eu un problème similaire et tous les problèmes ci-dessus ne le résolvent pas entièrement. Je suis également intéressé par le nom du fichier contenant les lignes correspondantes. Ma solution:

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

NB: Le motif dans mon cas correspond toujours à la première ligne.

Shokrof
la source