Question grep un fichier, mais montre plusieurs lignes environnantes?


J'aimerais grep pour une chaîne, mais montre aussi les cinq lignes précédentes et les cinq lignes suivantes ainsi que la ligne correspondante. Comment serais-je capable de faire ça?


2748
2017-08-12 17:55


origine


Réponses:


Pour BSD ou GNOU  grep vous pouvez utiliser -B num pour définir combien de lignes avant le match et -A num pour le nombre de lignes après le match.

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.


3667
2017-08-12 17:57



-A et -B travaillera, comme le fera -C n (pour n lignes de contexte), ou juste -n (pour n lignes de contexte).


520
2017-08-12 17:59



ack fonctionne avec des arguments similaires à grep, et accepte -C. Mais c'est généralement mieux pour chercher dans le code.


66
2017-09-07 11:13



grep astring myfile -A 5 -B 5

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


32
2017-08-12 17:58



J'utilise normalement

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

Beaucoup d'outils comme grep ont aussi de très bons fichiers man aussi. Je me trouve en référence à Page de man de grep beaucoup parce qu'il y a tellement de choses que vous pouvez faire avec.

man grep

De nombreux outils GNU ont aussi page d'information cela peut avoir plus d'informations utiles en plus de la page de manuel.

info grep

16
2017-08-12 18:42



Recherchez "17655" dans "/some/file.txt" en affichant 10 lignes de contexte avant et après (en utilisant Awk), sortie précédée d'un numéro de ligne suivi d'un deux-points. Utilisez ceci sur Solaris quand 'grep' ne supporte pas 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;

8
2017-10-08 00:21



Utiliser 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

5
2018-01-12 11:25



ripgrep

Si vous vous souciez de la performance, utilisez ripgrep qui a une syntaxe similaire à grep, par exemple.

rg -C5 "pattern" .

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

Il y a aussi des paramètres tels que -A/--after-context et -B/--before-context.

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


2
2018-04-11 10:28



Voici la @Ygor solution dans awk

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

Note: Remplacer a et b variables avec nombre de lignes avant et après.

C'est particulièrement utile pour les systèmes qui ne supportent pas grep -A, -B et -C paramètres.


0
2018-04-11 10:24