grep un fichier, mais montre plusieurs lignes environnantes?


3421

Je voudrais greppour une chaîne, mais aussi montrer les cinq lignes précédentes et les cinq lignes suivantes ainsi que la ligne correspondante. Comment pourrais-je faire cela?


3
Je garde une copie du script perl de Brendan Gregg à cet effet. Fonctionne bien.
Ethan Post

6
Pour une solution qui fonctionne sur Solaris, consultez ce lien .
jahroy

107
man grep | grep -C 1 context:)
StvnW

20
man grep | grep -C 1 "\-C";)
Anders B

9
@StvnW ... Je ne sais pas s'il faut appeler cette méta (dans un contexte plus général, plutôt que SO), ni comment l'appeler. Vous avez répondu à la question en montrant comment utiliser la réponse pour trouver la réponse.
bballdave025

Réponses:


4540

Pour BSD ou GNU, grep vous pouvez utiliser -B numpour définir le nombre de lignes avant la correspondance et -A numle nombre de lignes après la correspondance.

grep -B 3 -A 2 foo README.txt

Si vous voulez le même nombre de lignes avant et après, vous pouvez utiliser -C num.

grep -C 3 foo README.txt

Cela montrera 3 lignes avant et 3 lignes après.


56
C'est bien mais malheureusement le grep Solaris ne le supporte pas. Voir ce lien pour solaris: unix.com/solaris/33533-grep-display-few-lines-before-after.html
2011

9
Ok, mais que faire si vous voulez afficher toutes les lignes de sortie après le match? grep -A0 et grep -A-1 ne le coupent pas ...
g33kz0r

2
ne fonctionne pas pour moi pour une raison quelconque, bien que mentionné dans mes pages de manuel.
Hayri Uğur Koltuk

2
Si vous êtes env HP-UX, aucune des versions grep ne fonctionnera comme dans Solaris. A pu utiliser le lien Solaris mais remplacer nawk par awk dans ce lien.
zkarthik

6
-n est pour les numéros de ligne, mais pour certaines versions de grep -n # affichera # lignes environnantes (comme -c) avec des numéros de ligne. C'est un raccourci utile qui est mon choix lorsque j'ai besoin de contexte.
Anthony DiSanti

607

-Aet -Bfonctionnera, comme le fera -C n(pour les nlignes de contexte), ou tout simplement -n(pour les nlignes de contexte ... tant que n est 1 à 9).


J'ai essayé le -nformat et j'ai découvert qu'il ne fonctionnait que jusqu'à 9. Car 15il renvoie 5 lignes
Deepak Mahakale

8
@DeepakMahakale Ceci est probablement lié à la façon dont les arguments / options de ligne de commande sont généralement analysés par les programmes POSIX. Le spécificateur d'option est un seul caractère (tel que -A, -Bou -C). Habituellement, le spécificateur d'option est suivi d'une valeur ( -o a.outpour spécifier le fichier de sortie dans GCC), mais il peut également fonctionner comme un simple commutateur / indicateur ( -gpour activer les informations de débogage dans GCC). Cependant, les espaces entre les options sont facultatifs, donc pour les options sans valeur, il est possible de les fusionner ( -ABC), ce qui signifie que cela -15est interprété -1 -5(deux options distinctes) et le -5remplace le -1.
natiiix

1
-5 est plus rapide que les deux -A 5 -B 5. Ceux-ci ne sont pas destinés à être utilisés ensemble. Il est plus propre aux autres lecteurs du script si vous choisissez -A ou -B ou -C sur -9.
Eric Aldinger

77

ack fonctionne avec des arguments similaires à grep et accepte -C. Mais il est généralement préférable de rechercher dans le code.


5
ack prend également en charge -A -B.
Shuo

Ack est meilleur que grep à bien des égards. C'est plus rapide avec une syntaxe plus simple.
chim

1
grep a l'avantage d'être installé par défaut sur de nombreux systèmes.
Marc Z

1
@MarcZ: Certes, grep est plus susceptible d'être installé par défaut qu'ack, mais ack est un script portable et autonome. Il n'est pas nécessaire de le compiler ou de l'installer dans un répertoire système tel que / usr / bin /. Une fois qu'il est téléchargé et placé dans un répertoire répertorié dans $ PATH (et son ensemble de bits d'autorisation eXecute), il devrait fonctionner immédiatement. (Aucun privilège sudo ou root n'est requis pour faire fonctionner ack.)
JL

Cette question est à propos grep, pas sûr de l'utiliser pour "faire de la publicité" ack(qui est un excellent outil, en effet) est une bonne idée ...
MonsieurDart

39
grep astring myfile -A 5 -B 5

Cela va grep "monfichier" pour "astring", et afficher 5 lignes avant et après chaque match


19
"grep astring myfile -C 5" fera de même
Syed Siraj Uddin

20

J'utilise normalement

grep searchstring file -C n # n for number of lines of context up and down

De nombreux outils comme grep ont également de très bons fichiers man. Je me réfère souvent à la page de manuel de grep car il y a tellement de choses que vous pouvez faire avec.

man grep

De nombreux outils GNU ont également une page d'informations qui peut contenir des informations plus utiles en plus de la page de manuel.

info grep

13

Utilisez grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM

Vous n'avez pas lu la réponse acceptée? Vous venez de répéter ce qui a déjà été dit sur une question vieille de presque 10 ans ...
Yokai

7
Oh je suis désolé Yokai. Mais je ne lis rien sur l'accueil de la section d'aide de grep pour récupérer la réponse.
Chiel ten Brinke

1
@Yokai Outre ce que Chiel ten Brinke a dit, la réponse acceptée ne mentionne pas les options longues
user3738870

11

Recherchez «17655» dans «/some/file.txt» montrant le contexte de 10 lignes avant et après (en utilisant Awk), la sortie précédée du numéro de ligne suivi de deux points. Utilisez-le sur Solaris lorsque 'grep' ne prend pas en charge les options "- [ACB]".

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;

7

ripgrep

Si vous vous souciez des performances, utilisez ripgrepune syntaxe similaire à grep, par exemple

rg -C5 "pattern" .

-C, --context NUM- Afficher NUM lignes avant et après chaque match.

Il existe également des paramètres tels que -A/ --after-contextet -B/ --before-context.

L'outil est construit sur le moteur de regex de Rust, ce qui le rend très efficace sur les grandes données.


5

Voici la solution @Ygor enawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

Remarque: remplacez aet bvariables par le nombre de lignes avant et après.

Il est particulièrement utile pour le système qui ne supporte pas de grep -A, -Bet les -Cparamètres.


4
$ grep thestring thefile -5

-5vous obtient des 5lignes au-dessus et au-dessous du match 'thestring' est équivalent à -C 5ou -A 5 -B 5.


4

Grep a une option appelée Context Line Control, vous pouvez utiliser le --context, simplement,

| grep -C 5

ou

| grep -5

Devrait faire l'affaire


1

J'utilise pour faire de la manière compacte

grep -5 string file

C'est l'équivalent de

grep -A 5 -B 5 string file

0

Si vous recherchez souvent du code, AG le chercheur argent est beaucoup plus efficace (c'est-à-dire plus rapide) que grep.

Vous affichez les lignes de contexte en utilisant l'option -C.

Par exemple:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.