récupérer un fichier, mais afficher plusieurs lignes environnantes ?
-
08-06-2019 - |
Question
J'aimerais grep
pour une chaîne, mais affiche également les cinq lignes précédentes et les cinq lignes suivantes ainsi que la ligne correspondante.Comment pourrais-je faire cela ?
La solution
Pour BSD ou GNOU grep
vous pouvez utiliser -B num
pour définir le nombre 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 affichera 3 lignes avant et 3 lignes après.
Autres conseils
-A
et -B
fonctionnera, tout comme -C n
(pour n
lignes de contexte), ou simplement -n
(pour n
lignes de contexte...tant que n est compris entre 1 et 9).
ack fonctionne avec des arguments similaires à grep et accepte -C
.Mais c'est généralement mieux pour effectuer une recherche dans le code.
grep astring myfile -A 5 -B 5
Cela récupérera "myfile" pour "astring" et affichera 5 lignes avant et après chaque correspondance
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 retrouve à faire référence à page de manuel de grep beaucoup parce que vous pouvez faire tellement de choses avec.
man grep
De nombreux outils GNU ont également un page d'informations qui peut contenir des informations plus utiles en plus de la page de manuel.
info grep
Recherchez "17655" dans "/some/file.txt" affichant le contexte de 10 lignes avant et après (en utilisant Awk), 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;
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
ripgrep
Si vous vous souciez des performances, utilisez ripgrep
qui a une 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-context
et -B
/--before-context
.
L'outil est construit sur Le moteur d'expression régulière de Rust ce qui le rend très efficace sur les grandes données.
$grep thestring thefile -5
-5 vous donne 5 lignes au-dessus et en dessous du match 'thestring' est équivalent à -c 5 ou -a 5 -b 5
Grep a une option appelée Context Line Control
, vous pouvez utiliser le --contect
en cela, tout simplement,
| grep -C 5
ou
| grep -5
Devrait faire l'affaire
Voici la Solution @Ygor 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 le nombre de lignes avant et après.
C'est particulièrement utile pour les systèmes qui ne prennent pas en charge grep -A
, -B
et -C
paramètres.