web-dev-qa-db-fra.com

Utilisation de sed pour supprimer toutes les lignes entre deux motifs correspondants

J'ai un fichier quelque chose comme:

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah

Comment puis-je utiliser une commande sed pour supprimer toutes les lignes entre le # et $ ligne? Le résultat deviendra donc:

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

Pouvez-vous, s'il vous plaît, donner une explication également?

54
Ken

Utilisez cette commande sed pour y parvenir:

sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt

Utilisateurs Mac (pour empêcher extra characters at the end of d command erreur) doit ajouter des points-virgules avant les crochets de fermeture

sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt

PRODUCTION

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

Explication:

  • /^#/,/^\$/ correspondra à tout le texte entre les lignes commençant par # aux lignes commençant par $. ^ est utilisé pour le début du caractère de ligne. $ est un caractère spécial qui doit donc être échappé.
  • /^#/! signifie faire suivre si le début de la ligne n'est pas #
  • /^$/! signifie faire suivre si le début de la ligne n'est pas $
  • d signifie supprimer

Donc, globalement, il correspond d'abord à toutes les lignes de ^# à ^\$ puis à partir de ces lignes correspondantes, trouver des lignes qui ne correspondent pas^# et ne correspondent pas^\$ et en les supprimant à l'aide de d.

48
anubhava
$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3
34
Lri

En général, si vous avez un fichier avec le contenu du formulaire abcde, où la section a précède le modèle b, alors la section c précède le modèle d, puis la section e suit, et vous appliquez les commandes sed suivantes, vous obtenez les résultats suivants.

Dans cette démonstration, la sortie est représentée par => abcde, où les lettres indiquent les sections qui figureraient dans la sortie. Ainsi, ae affiche une sortie de sections uniquement a et e, ace serait des sections a, c, et e, etc.

Notez que si b ou d apparaissent dans la sortie, ce sont les modèles qui apparaissent (c'est-à-dire qu'ils sont traités comme s'il s'agissait de sections dans la sortie).

Ne confondez pas non plus le /d/ modèle avec la commande d. Le commandement est toujours au bout de ces démonstrations. Le motif est toujours entre le //.

  • sed -n -e '/b/,/d/!p' abcde => ae
  • sed -n -e '/b/,/d/p' abcde => bcd
  • sed -n -e '/b/,/d/{//!p}' abcde => c
  • sed -n -e '/b/,/d/{//p}' abcde => bd
  • sed -e '/b/,/d/!d' abcde => bcd
  • sed -e '/b/,/d/d' abcde => ae
  • sed -e '/b/,/d/{//!d}' abcde => abde
  • sed -e '/b/,/d/{//d}' abcde => as
7
fbicknel

Une autre approche avec sed:

sed '/^#/,/^\$/{//!d;};' file
  • /^#/,/^\$/: à partir de la ligne commençant par # jusqu'à la ligne suivante commençant par $
  • //!d: supprime toutes les lignes sauf celles correspondant aux modèles d'adresse
5
SLePort

J'ai fait quelque chose comme ça il y a longtemps et c'était quelque chose comme:

sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"

Ce qui est quelque chose comme:

  • -n supprime toutes les sorties
  • -e "1,/# ID 1/ p" exécute à partir de la première ligne jusqu'à ce que votre motif et p (print)
  • -e "/\$ description 1/,$ p" exécuter du deuxième motif jusqu'à la fin et p (imprimer).

Je peux me tromper avec certains des fuites sur les cordes, alors veuillez vérifier.

3
Ricardo Marimon