Agence web » Actualités du digital » Comment utiliser la commande sed sur Linux

Comment utiliser la commande sed sur Linux

Cela peut sembler fou, mais le Linux sed est un éditeur de texte sans interface. Vous pouvez l'utiliser à partir de la ligne de commande pour manipuler du texte dans des fichiers et des flux. Nous allons vous montrer comment exploiter sa puissance.

La puissance de sed

le sed la commande est un peu comme les échecs: il faut une heure pour apprendre les bases et toute une vie pour les maîtriser (ou, au moins, beaucoup de pratique). Nous allons vous montrer une sélection de gambits d'ouverture dans chacune des principales catégories de sed Fonctionnalité.

sed est un éditeur de flux qui fonctionne sur une entrée canalisée ou des fichiers de texte. Cependant, il ne dispose pas d'une interface d'édition de texte interactive. Au lieu de cela, vous fournissez des instructions à suivre pendant qu'il fonctionne dans le texte. Tout cela fonctionne dans Bash et d'autres shells de ligne de commande.

Avec sed vous pouvez effectuer toutes les opérations suivantes:

  • Sélectionnez le texte
  • Texte de remplacement
  • Ajouter des lignes au texte
  • Supprimer des lignes du texte
  • Modifier (ou conserver) un fichier d'origine

Nous avons structuré nos exemples pour introduire et démontrer des concepts, pas pour produire le plus simple (et le moins accessible) sed commandes. Cependant, les fonctionnalités de filtrage et de sélection de texte de sed s'appuyer fortement sur les expressions régulières (expressions régulières). Vous allez avoir besoin de vous familiariser avec ceux-ci pour tirer le meilleur parti de sed.

Un exemple simple

Tout d'abord, nous allons utiliser echo envoyer du texte à sed à travers un tuyau, et ont sed remplacer une partie du texte. Pour ce faire, nous tapons ce qui suit:

echo howtogonk | sed 's/gonk/geek/'

le echo commande envoie "howtogonk" dans sedet notre règle de substitution simple (le «s» signifie substitution) est appliquée. sed recherche une occurrence de la première chaîne dans le texte d'entrée et remplace toutes les correspondances par la seconde.

La chaîne «gonk» est remplacée par «geek» et la nouvelle chaîne est imprimée dans la fenêtre du terminal.

Les substitutions sont probablement l'utilisation la plus courante de sed. Avant de pouvoir approfondir les substitutions, nous devons cependant savoir comment sélectionner et faire correspondre le texte.

Sélection de texte

Nous allons avoir besoin d'un fichier texte pour nos exemples. Nous en utiliserons un qui contient une sélection de vers du poème épique de Samuel Taylor Coleridge «Le Rime de l'ancien marin».

Nous tapons ce qui suit pour y jeter un œil avec less:

less coleridge.txt

Pour sélectionner certaines lignes du fichier, nous fournissons les lignes de début et de fin de la plage que nous voulons sélectionner. Un seul numéro sélectionne cette ligne.

Pour extraire les lignes un à quatre, nous tapons cette commande:

sed -n '1,4p' coleridge.txt

Notez la virgule entre 1 et 4. le p signifie «imprimer les lignes correspondantes». Par défaut, sed imprime toutes les lignes. Nous verrions tout le texte du fichier avec les lignes correspondantes imprimées deux fois. Pour éviter cela, nous utiliserons le -n (silencieux) option pour supprimer le texte inégalé.

Nous modifions les numéros de ligne afin de pouvoir sélectionner un verset différent, comme indiqué ci-dessous:

sed -n '6,9p' coleridge.txt

Nous pouvons utiliser le -e (expression) option pour effectuer plusieurs sélections. Avec deux expressions, nous pouvons sélectionner deux versets, comme ceci:

sed -n -e '1,4p' -e '31,34p' coleridge.txt

Si nous réduisons le premier nombre dans la deuxième expression, nous pouvons insérer un blanc entre les deux versets. Nous tapons ce qui suit:

sed -n -e '1,4p' -e '30,34p' coleridge.txt

Nous pouvons également choisir une ligne de départ et dire sed pour parcourir le fichier et imprimer des lignes alternatives, toutes les cinq lignes, ou pour sauter un nombre quelconque de lignes. La commande est similaire à celles que nous avons utilisées ci-dessus pour sélectionner une plage. Cette fois, cependant, nous utiliserons un tilde (~) au lieu d'une virgule pour séparer les nombres.

Le premier chiffre indique la ligne de départ. Le deuxième chiffre indique sed quelles lignes après la ligne de départ nous voulons voir. Le nombre 2 signifie toutes les deux lignes, 3 signifie toutes les trois lignes, et ainsi de suite.

Nous tapons ce qui suit:

sed -n '1~2p' coleridge.txt

Vous ne saurez pas toujours où se trouve le texte que vous recherchez dans le fichier, ce qui signifie que les numéros de ligne ne seront pas toujours d'une grande aide. Cependant, vous pouvez également utiliser sed pour sélectionner des lignes contenant des motifs de texte correspondants. Par exemple, extrayons toutes les lignes commençant par "Et".

Le caret (^) représente le début de la ligne. Nous allons inclure notre terme de recherche dans des barres obliques (/). Nous incluons également un espace après "Et" afin que des mots comme "Android" ne soient pas inclus dans le résultat.

En train de lire sed les scripts peuvent être un peu difficiles au début. le /p signifie «imprimer», tout comme dans les commandes que nous avons utilisées ci-dessus. Dans la commande suivante, cependant, une barre oblique la précède:

sed -n '/^And /p' coleridge.txt

Trois lignes commençant par «Et» sont extraites du fichier et affichées pour nous.

Faire des substitutions

Dans notre premier exemple, nous vous avons montré le format de base suivant pour un sed substitution:

echo howtogonk | sed 's/gonk/geek/'

le s raconte sed c'est une substitution. La première chaîne est le modèle de recherche, et la seconde est le texte avec lequel nous voulons remplacer ce texte correspondant. Bien sûr, comme pour tout ce qui concerne Linux, le diable est dans les détails.

Nous tapons ce qui suit pour changer toutes les occurrences de «jour» en «semaine» et donner plus de temps au marin et à l'albatros pour se lier:

sed -n 's/day/week/p' coleridge.txt

Dans la première ligne, seule la deuxième occurrence de «jour» est modifiée. Ceci est dû au fait sed s'arrête après le premier match par ligne. Nous devons ajouter un «g» à la fin de l'expression, comme indiqué ci-dessous, pour effectuer une recherche globale afin que toutes les correspondances de chaque ligne soient traitées:

sed -n 's/day/week/gp' coleridge.txt

Cela correspond à trois des quatre de la première ligne. Parce que le premier mot est "Jour", et sed est sensible à la casse, il ne considère pas que cette instance est la même que "jour".

Nous tapons ce qui suit, en ajoutant un i à la commande à la fin de l'expression pour indiquer l'insensibilité à la casse:

sed -n 's/day/week/gip' coleridge.txt

Cela fonctionne, mais vous ne voudrez peut-être pas toujours activer l'insensibilité à la casse pour tout. Dans ces cas, vous pouvez utiliser un groupe d'expressions régulières pour ajouter une insensibilité à la casse spécifique au modèle.

Par exemple, si nous mettons des caractères entre crochets (()), ils sont interprétés comme «n'importe quel caractère de cette liste de caractères».

Nous tapons ce qui suit et incluons "D" et "d" dans le groupe, pour nous assurer qu'il correspond à la fois à "Jour" et "jour":

sed -n 's/(Dd)ay/week/gp' coleridge.txt

Nous pouvons également limiter les substitutions aux sections du fichier. Disons que notre fichier contient un espacement étrange dans le premier verset. Nous pouvons utiliser la commande familière suivante pour voir le premier verset:

sed -n '1,4p' coleridge.txt

Nous allons rechercher deux espaces et les remplacer par un. Nous le ferons à l'échelle mondiale afin que l'action se répète sur toute la ligne. Pour être clair, le modèle de recherche est l'espace, l'astérisque espace (*), et la chaîne de substitution est un espace unique. le 1,4 limite la substitution aux quatre premières lignes du fichier.

Nous mettons tout cela ensemble dans la commande suivante:

sed -n '1,4 s/  */ /gp' coleridge.txt

Cela fonctionne bien! Le modèle de recherche est ce qui est important ici. L'astérisque (*) représente zéro ou plus du caractère précédent, qui est un espace. Ainsi, le modèle de recherche recherche des chaînes d'un espace ou plus.

Si nous substituons un seul espace à une séquence de plusieurs espaces, nous rétablirons l'espacement régulier du fichier, avec un seul espace entre chaque mot. Dans certains cas, cela remplacera également un seul espace par un seul espace, mais cela n'affectera rien, nous obtiendrons toujours le résultat souhaité.

Si nous tapons ce qui suit et réduisons le modèle de recherche à un seul espace, vous verrez immédiatement pourquoi nous devons inclure deux espaces:

sed -n '1,4 s/ */ /gp' coleridge.txt

Étant donné que l'astérisque correspond à zéro ou plus du caractère précédent, il voit chaque caractère qui n'est pas un espace comme un "espace zéro" et lui applique la substitution.

Cependant, si nous incluons deux espaces dans le modèle de recherche, sed doit trouver au moins un caractère espace avant d'appliquer la substitution. Cela garantit que les personnages non spatiaux resteront intacts.

Nous tapons ce qui suit, en utilisant le -e (expression) que nous avons utilisée précédemment, ce qui nous permet de faire deux substitutions ou plus simultanément:

sed -n -e 's/motion/flutter/gip' -e 's/ocean/gutter/gip' coleridge.txt

Nous pouvons obtenir le même résultat si nous utilisons un point-virgule (;) Pour séparer les deux expressions, comme ceci:

sed -n 's/motion/flutter/gip;s/ocean/gutter/gip' coleridge.txt

Lorsque nous avons échangé «jour» pour «semaine» dans la commande suivante, l'instance de «jour» dans l'expression «bien un jour» a également été échangée:

sed -n 's/(Dd)ay/week/gp' coleridge.txt

Pour éviter cela, nous ne pouvons tenter des substitutions que sur des lignes qui correspondent à un autre modèle. Si nous modifions la commande pour avoir un modèle de recherche au début, nous ne considérerons que l’opération sur les lignes qui correspondent à ce modèle.

Nous tapons ce qui suit pour faire de notre modèle de correspondance le mot «après»:

sed -n '/after/ s/(Dd)ay/week/gp' coleridge.txt

Cela nous donne la réponse que nous voulons.

Substitutions plus complexes

Faisons une pause à Coleridge et utilisons sed pour extraire des noms du etc/passwd fichier.

Il existe des moyens plus courts de le faire (plus à ce sujet plus tard), mais nous utiliserons le moyen le plus long ici pour démontrer un autre concept. Chaque élément correspondant dans un modèle de recherche (appelé sous-expressions) peut être numéroté (jusqu'à un maximum de neuf éléments). Vous pouvez ensuite utiliser ces numéros dans votre sed pour référencer des sous-expressions spécifiques.

Vous devez mettre la sous-expression entre parenthèses (()) pour que cela fonctionne. Les parenthèses doivent également être précédées d'une barre oblique inverse () pour éviter qu'ils ne soient traités comme un personnage normal.

Pour ce faire, vous devez taper ce qui suit:

sed 's/((^:)*).*/1/' /etc/passwd

Décomposons ceci:

  • sed 's/: le sed et le début de l'expression de substitution.
  • (: La parenthèse d'ouverture (() entourant la sous-expression, précédée d'une barre oblique inverse ().
  • (^:)*: La première sous-expression du terme de recherche contient un groupe entre crochets. Le caret (^) signifie «non» lorsqu'il est utilisé en groupe. Un groupe signifie tout personnage qui n'est pas un deux-points (:) sera accepté comme match.
  • ): La parenthèse fermante ()) avec une barre oblique inverse précédente ().
  • .*: Cette deuxième sous-expression de recherche signifie «n'importe quel caractère et n'importe quel nombre».
  • /1: La portion de substitution de l'expression contient 1 précédé d'une barre oblique inverse (). Cela représente le texte qui correspond à la première sous-expression.
  • /': La barre oblique de fermeture (/) et guillemet simple (') mettre fin à la sed commander.

Cela signifie que nous allons rechercher toute chaîne de caractères ne contenant pas de deux-points (:), qui sera la première instance de correspondance de texte. Ensuite, nous recherchons autre chose sur cette ligne, qui sera la deuxième instance de correspondance de texte. Nous allons remplacer la ligne entière par le texte correspondant à la première sous-expression.

Chaque ligne du /etc/passwd le fichier commence par un nom d'utilisateur terminé par deux points. Nous faisons correspondre tout jusqu'au premier deux-points, puis substituons cette valeur à la ligne entière. Nous avons donc isolé les noms d'utilisateur.

Ensuite, nous allons mettre la deuxième sous-expression entre parenthèses (()) afin que nous puissions également y faire référence par numéro. Nous remplacerons également 1 avec 2. Notre commande va maintenant remplacer la ligne entière par tout depuis le premier deux-points (:) jusqu'à la fin de la ligne.

Nous tapons ce qui suit:

sed 's/((^:)*)(.*)/2/' /etc/passwd

Ces petits changements inversent le sens de la commande, et nous obtenons tout sauf les noms d'utilisateur.

Voyons maintenant la manière simple et rapide de procéder.

Notre terme de recherche provient du premier côlon (:) jusqu'à la fin de la ligne. Parce que notre expression de substitution est vide (//), nous ne remplacerons le texte correspondant par rien.

Donc, nous tapons ce qui suit, coupant tout du premier côlon (:) jusqu'à la fin de la ligne, en ne laissant que les noms d'utilisateur:

sed 's/:.*//" /etc/passwd

Regardons un exemple dans lequel nous référençons les première et deuxième correspondances dans la même commande.

Nous avons un fichier de virgules (,) séparant le prénom et le nom. Nous voulons les répertorier comme «nom, prénom». On peut utiliser cat, comme illustré ci-dessous, pour voir le contenu du fichier:

cat geeks.txt

Comme beaucoup de sed commandes, celle-ci pourrait sembler impénétrable au premier abord:

sed 's/^(.*),(.*)$/2,1 /g' geeks.txt

Il s'agit d'une commande de substitution comme les autres que nous avons utilisées, et le modèle de recherche est assez simple. Nous allons le détailler ci-dessous:

  • sed 's/: La commande de substitution normale.
  • ^: Parce que le curseur n'est pas dans un groupe (()), cela signifie «Le début de la ligne».
  • (.*),: La première sous-expression est un nombre quelconque de caractères. Il est placé entre parenthèses (()), dont chacun est précédé d'une barre oblique inverse () afin que nous puissions y faire référence par numéro. Jusqu'à présent, l'ensemble de notre modèle de recherche se traduit par une recherche depuis le début de la ligne jusqu'à la première virgule (,) pour n'importe quel nombre de caractères.
  • (.*): La sous-expression suivante est (encore) n'importe quel nombre de n'importe quel caractère. Il est également placé entre parenthèses (()), tous deux précédés d'une barre oblique inverse () afin que nous puissions référencer le texte correspondant par numéro.
  • $/: Le signe dollar ($) représente la fin de la ligne et permettra à notre recherche de se poursuivre jusqu'à la fin de la ligne. Nous l'avons utilisé simplement pour introduire le signe dollar. Nous n'en avons pas vraiment besoin ici, comme l'astérisque (*) irait au bout de la ligne dans ce scénario. La barre oblique (/) termine la section du modèle de recherche.
  • 2,1 /g': Parce que nous avons mis nos deux sous-expressions entre parenthèses, nous pouvons les désigner toutes les deux par leur nombre. Parce que nous voulons inverser l'ordre, nous les tapons comme second-match,first-match. Les chiffres doivent être précédés d'une barre oblique inverse ().
  • /g: Cela permet à notre commande de fonctionner globalement sur chaque ligne.
  • geeks.txt: Le fichier sur lequel nous travaillons.

Vous pouvez également utiliser la commande Couper (c) pour remplacer des lignes entières qui correspondent à votre modèle de recherche. Nous tapons ce qui suit pour rechercher une ligne contenant le mot «cou» et la remplacer par une nouvelle chaîne de texte:

sed '/neck/c Around my wrist was strung' coleridge.txt

Notre nouvelle ligne apparaît maintenant au bas de notre extrait.

Insertion de lignes et de texte

Nous pouvons également insérer de nouvelles lignes et du texte dans notre fichier. Pour insérer de nouvelles lignes après celles qui correspondent, nous utiliserons la commande Ajouter (a).

Voici le fichier avec lequel nous allons travailler:

cat geeks.txt

Nous avons numéroté les lignes pour rendre cela un peu plus facile à suivre.

Nous tapons ce qui suit pour rechercher les lignes qui contiennent le mot «He» et insérons une nouvelle ligne en dessous:

sed '/He/a --> Inserted!' geeks.txt

Nous tapons ce qui suit et incluons la commande d'insertion (i) pour insérer la nouvelle ligne au-dessus de celles qui contiennent le texte correspondant:

sed '/He/i --> Inserted!' geeks.txt

Nous pouvons utiliser l'esperluette (&), qui représente le texte correspondant d'origine, pour ajouter un nouveau texte à une ligne correspondante. 1 , 2, et ainsi de suite, représentent des sous-expressions correspondantes.

Pour ajouter du texte au début d'une ligne, nous allons utiliser une commande de substitution qui correspond à tout sur la ligne, combinée à une clause de remplacement qui combine notre nouveau texte avec la ligne d'origine.

Pour faire tout cela, nous tapons ce qui suit:

sed 's/.*/--> Inserted &/' geeks.txt

Nous tapons ce qui suit, y compris le G , qui ajoutera une ligne vierge entre chaque ligne:

sed 'G' geeks.txt

Si vous souhaitez ajouter deux lignes vides ou plus, vous pouvez utiliser G;G, G;G;G, etc.

Suppression de lignes

La commande Supprimer (d) supprime les lignes qui correspondent à un modèle de recherche ou celles spécifiées avec des numéros de ligne ou des plages.

Par exemple, pour supprimer la troisième ligne, nous tapons ce qui suit:

sed '3d' geeks.txt

Pour supprimer la plage de lignes quatre à cinq, nous tapons ce qui suit:

sed '4,5d' geeks.txt

Pour supprimer des lignes en dehors d'une plage, nous utilisons un point d'exclamation (!), comme indiqué ci-dessous:

sed '6,7!d' geeks.txt

Sauvegarder vos modifications

Jusqu'à présent, tous nos résultats ont été imprimés dans la fenêtre du terminal, mais nous ne les avons encore enregistrés nulle part. Pour les rendre permanents, vous pouvez soit écrire vos modifications dans le fichier d'origine, soit les rediriger vers un nouveau.

Le remplacement de votre fichier d'origine nécessite une certaine prudence. Si ton sed La commande est incorrecte, vous pouvez apporter des modifications au fichier d'origine qui sont difficiles à annuler.

Pour une tranquillité d'esprit, sed peut créer une sauvegarde du fichier d'origine avant d'exécuter sa commande.

Vous pouvez utiliser l'option sur place (-i) dire sed pour écrire les modifications dans le fichier d'origine, mais si vous lui ajoutez une extension de fichier, sed sauvegardera le fichier d'origine dans un nouveau. Il aura le même nom que le fichier d'origine, mais avec une nouvelle extension de fichier.

Pour le démontrer, nous rechercherons toutes les lignes contenant le mot "He" et les supprimerons. Nous allons également sauvegarder notre fichier d'origine dans un nouveau en utilisant l'extension BAK.

Pour faire tout cela, nous tapons ce qui suit:

sed -i'.bak' '/^.*He.*$/d' geeks.txt

Nous tapons ce qui suit pour nous assurer que notre fichier de sauvegarde est inchangé:

cat geeks.txt.bak

Nous pouvons également taper ce qui suit pour rediriger la sortie vers un nouveau fichier et obtenir un résultat similaire:

sed -i'.bak' '/^.*He.*$/d' geeks.txt > new_geeks.txt

Nous utilisons cat pour confirmer que les modifications ont été écrites dans le nouveau fichier, comme indiqué ci-dessous:

cat new_geeks.txt

Ayant séduit tout ça

Comme vous l’avez probablement remarqué, même cette introduction rapide sed est assez long. Il y a beaucoup à faire avec cette commande, et vous pouvez faire encore plus avec.

Nous espérons cependant que ces concepts de base ont fourni une base solide sur laquelle vous pouvez vous baser pour continuer à en apprendre davantage.

★★★★★