web-dev-qa-db-fra.com

Demandez à sed d'ignorer les lignes qui ne correspondent pas

Comment puis-je faire sed filtrer les lignes correspondantes selon une expression, mais ignorer les lignes qui ne correspondent pas, au lieu de les laisser imprimer?

Par exemple, je veux exécuter scalac (le compilateur Scala) sur un ensemble de fichiers et lire à partir de son -verbose afficher le .class fichiers créés. scalac -verbose affiche un tas de messages, mais nous ne sommes intéressés que par ceux de la forme [wrote some-class-name.class]. Voici ce que je fais actuellement (|& est le moyen de bash 4.0 pour diriger stderr vers le programme suivant):

$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'

Cela extraira les noms de fichiers des messages qui nous intéressent, mais permettra également à tous les autres messages de passer inchangés! Bien sûr, nous pourrions faire ceci:

$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
  sed 's/^\[wrote \(.*\.class\)\]$/\1/'

qui fonctionne mais ressemble beaucoup à contourner le vrai problème, qui est de savoir comment demander à sed d'ignorer les lignes non correspondantes de l'entrée. Alors, comment on fait ça?

79
Paggas

Une autre façon avec plain sed:

sed -e 's/.../.../;t;d'

s/// est une substitution, t sans aucune étiquette ignore conditionnellement toutes les commandes suivantes, d supprime la ligne.

Pas besoin de Perl ou grep.

(édité après la suggestion de Nicholas Riley)

80
liori

Si vous ne souhaitez pas imprimer des lignes qui ne correspondent pas, vous pouvez utiliser la combinaison de

  • -n option qui indique à sed de ne pas imprimer
  • p drapeau qui indique à sed d'imprimer ce qui correspond

Cela donne:

sed -n 's/.../.../p'
223
mouviciel

Utilisez Perl:

... |& Perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/'
1
Greg Hewgill