Je veux filtrer plusieurs lignes avant et après une ligne correspondante dans un fichier.
Cela va supprimer la ligne que je ne veux pas:
$ grep -v "line that i don't want"
Et cela imprimera les 2 lignes avant et après la ligne que je ne veux pas:
$ grep -C 2 "line that i don't want"
Mais quand je les combine, il ne filtre pas les 2 lignes avant et après la ligne que je ne veux pas:
# does not remove 2 lines before and after the line I don't want: $ grep -v -C 2 "line that i don't want"
Comment filtrer non seulement la ligne que je ne veux pas, mais aussi les lignes avant et après? Je suppose que sed
serait mieux pour ça …
Edit: Je sais que cela pourrait se faire en quelques lignes de awk / Perl / Python / Ruby / etc, mais je veux savoir s’il y a un raccourci simple que je pourrais utiliser depuis la ligne de commande.
Essayez ceci:
sed 'h;:b;$b;N;N;/PATTERN/{N;d};$b;P;D' inputfile
Vous pouvez modifier le nombre de commandes N
avant le modèle pour affecter le nombre de lignes à supprimer.
Vous pouvez générer par programme une chaîne contenant le nombre de N
commandes:
C=2 # corresponds to grep -C N=N for ((i = 0; i < C - 1; i++)); do N=$N";N"; done sed "h;:b;\$b;$N;/PATTERN/{N;d};\$b;P;D" inputfile
Si les lignes sont toutes uniques, vous pouvez graver les lignes que vous souhaitez supprimer dans un fichier, puis utiliser ce fichier pour supprimer les lignes de l’original, par exemple
grep -C 2 "line I don't want" < A.txt > B.txt grep -f B.txt A.txt
awk 'BEGIN{n=2}{a[++i]=$0} /dont/{ for(j=1;j<=i-(n+1);j++)print a[j]; for(o=1;o<=n;o++)getline; delete a} END{for(i in a)print a[i]} ' file
Je pense que @ fxm27 a une excellente réponse bash-y.
J’appendais que vous pourriez résoudre ce problème d’une autre manière en utilisant egrep si vous connaissiez à l’avance les modèles des lignes suivantes.
command | egrep -v "words|from|lines|you|dont|want"
Cela fera un «OU inclusif», ce qui signifie qu’une ligne qui correspond à l’ un de ceux-ci sera exclue.
Je l’ai résolu avec deux grep séquentiels, en fait. Cela me semble beaucoup plus simple.
grep -C "match" yourfile | grep -v -f - yourfile