Unix / Linux - Expressions régulières avec SED
Dans ce chapitre, nous discuterons en détail des expressions régulières avec SED sous Unix.
Une expression régulière est une chaîne qui peut être utilisée pour décrire plusieurs séquences de caractères. Les expressions régulières sont utilisées par plusieurs commandes Unix différentes, notammented, sed, awk, grep, et dans une mesure plus limitée, vi.
Ici SED signifie stream editor. Cet éditeur orienté flux a été créé exclusivement pour l'exécution de scripts. Ainsi, toute l'entrée que vous y introduisez passe et va vers STDOUT et cela ne change pas le fichier d'entrée.
Invoquer sed
Avant de commencer, assurons-nous d'avoir une copie locale de /etc/passwd fichier texte avec lequel travailler sed.
Comme mentionné précédemment, sed peut être appelé en lui envoyant des données via un tube comme suit -
$ cat /etc/passwd | sed
Usage: sed [OPTION]... {script-other-script} [input-file]...
-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression = script
...............................
le cat la commande vide le contenu de /etc/passwd à sedà travers le tuyau dans l'espace de modèle de sed. L'espace de motif est le tampon de travail interne utilisé par sed pour ses opérations.
La syntaxe générale sed
Voici la syntaxe générale de sed -
/pattern/action
Ici, pattern est une expression régulière, et actionest l'une des commandes données dans le tableau suivant. Sipattern est omis, action est effectuée pour chaque ligne comme nous l'avons vu ci-dessus.
Le caractère barre oblique (/) qui entoure le motif est obligatoire car il est utilisé comme délimiteur.
Sr.No. | Gamme et description |
---|---|
1 | p Imprime la ligne |
2 | d Supprime la ligne |
3 | s/pattern1/pattern2/ Remplace la première occurrence de pattern1 par pattern2 |
Suppression de toutes les lignes avec sed
Nous allons maintenant comprendre comment supprimer toutes les lignes avec sed. Invoquez à nouveau sed; mais le sed est maintenant censé utiliser leediting command delete line, indiqué par la lettre unique d -
$ cat /etc/passwd | sed 'd'
$
Au lieu d'appeler sed en lui envoyant un fichier via un tube, le sed peut être invité à lire les données d'un fichier, comme dans l'exemple suivant.
La commande suivante fait exactement la même chose que dans l'exemple précédent, sans la commande cat -
$ sed -e 'd' /etc/passwd
$
Les adresses sed
Le sed prend également en charge les adresses. Les adresses sont soit des emplacements particuliers dans un fichier, soit une plage dans laquelle une commande d'édition particulière doit être appliquée. Lorsque le sed ne rencontre aucune adresse, il effectue ses opérations sur chaque ligne du fichier.
La commande suivante ajoute une adresse de base à la commande sed que vous avez utilisée -
$ cat /etc/passwd | sed '1d' |more
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$
Notez que le numéro 1 est ajouté avant le delete editcommander. Cela demande au sed d'exécuter la commande d'édition sur la première ligne du fichier. Dans cet exemple, le sed supprimera la première ligne de/etc/password et imprimez le reste du fichier.
Les gammes d'adresses sed
Nous allons maintenant comprendre comment travailler avec the sed address ranges. Alors que faire si vous souhaitez supprimer plus d'une ligne d'un fichier? Vous pouvez spécifier une plage d'adresses avec sed comme suit -
$ cat /etc/passwd | sed '1, 5d' |more
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$
La commande ci-dessus sera appliquée sur toutes les lignes de 1 à 5. Cela supprime les cinq premières lignes.
Essayez les plages d'adresses suivantes -
Sr.No. | Gamme et description |
---|---|
1 | '4,10d' Les lignes à partir de la 4 e jusqu'à ce que le 10 e sont supprimés |
2 | '10,4d' Seule la 10 e ligne est supprimée, car le sed ne fonctionne pas en sens inverse |
3 | '4,+5d' Cela correspond à la ligne 4 du fichier, supprime cette ligne, continue de supprimer les cinq lignes suivantes, puis cesse sa suppression et imprime le reste |
4 | '2,5!d' Cela supprime tout sauf à partir de la 2 ème à la 5 ème ligne |
5 | '1~3d' Cela supprime la première ligne, passe les trois lignes suivantes, puis supprime la quatrième ligne. Sed continue d'appliquer ce modèle jusqu'à la fin du fichier. |
6 | '2~2d' Cela indique à sed de supprimer la deuxième ligne, de passer à la ligne suivante, de supprimer la ligne suivante et de répéter jusqu'à ce que la fin du fichier soit atteinte |
sept | '4,10p' Les lignes à partir de 4 ème au 10 ème sont imprimées |
8 | '4,d' Cela génère l'erreur de syntaxe |
9 | ',10d' Cela générerait également une erreur de syntaxe |
Note - Lors de l'utilisation du p action, vous devez utiliser le -noption pour éviter la répétition de l'impression de ligne. Vérifiez la différence entre les deux commandes suivantes -
$ cat /etc/passwd | sed -n '1,3p'
Check the above command without -n as follows −
$ cat /etc/passwd | sed '1,3p'
La commande de substitution
La commande de substitution, désignée par s, remplacera toute chaîne que vous spécifiez par toute autre chaîne que vous spécifiez.
Pour remplacer une chaîne par une autre, le sed doit avoir les informations sur la fin de la première chaîne et le début de la chaîne de substitution. Pour cela, nous procédons à la réservation des deux chaînes avec la barre oblique (/) personnage.
La commande suivante remplace la première occurrence sur une ligne de la chaîne root avec la ficelle amrood.
$ cat /etc/passwd | sed 's/root/amrood/'
amrood:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
..........................
Il est très important de noter que sed ne remplace que la première occurrence sur une ligne. Si la racine de la chaîne apparaît plus d'une fois sur une ligne, seule la première correspondance sera remplacée.
Pour que le sed effectue une substitution globale, ajoutez la lettre g à la fin de la commande comme suit -
$ cat /etc/passwd | sed 's/root/amrood/g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
...........................
Drapeaux de substitution
Il existe un certain nombre d'autres indicateurs utiles qui peuvent être passés en plus du g drapeau, et vous pouvez en spécifier plusieurs à la fois.
Sr.No. | Drapeau et description |
---|---|
1 | g Remplace tous les matchs, pas seulement le premier match |
2 | NUMBER Remplace seulement NUMBER e match |
3 | p Si une substitution a été effectuée, imprime l'espace du motif |
4 | w FILENAME Si une substitution a été effectuée, écrit le résultat dans FILENAME |
5 | I or i Correspondance insensible à la casse |
6 | M or m En plus du comportement normal des caractères spéciaux des expressions régulières ^ et $, cet indicateur fait correspondre ^ la chaîne vide après une nouvelle ligne et $ pour correspondre à la chaîne vide avant une nouvelle ligne |
Utilisation d'un autre séparateur de chaînes
Supposons que vous deviez effectuer une substitution sur une chaîne qui inclut la barre oblique. Dans ce cas, vous pouvez spécifier un séparateur différent en fournissant le caractère désigné après les.
$ cat /etc/passwd | sed 's:/root:/amrood:g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
Dans l'exemple ci-dessus, nous avons utilisé : comme le delimiter au lieu de slash / parce que nous essayions de rechercher /root au lieu de la simple racine.
Remplacement par un espace vide
Utilisez une chaîne de substitution vide pour supprimer la chaîne racine du /etc/passwd déposer entièrement -
$ cat /etc/passwd | sed 's/root//g'
:x:0:0::/:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
Substitution d'adresse
Si vous souhaitez remplacer la chaîne sh avec la ficelle quiet uniquement à la ligne 10, vous pouvez le spécifier comme suit -
$ cat /etc/passwd | sed '10s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/quiet
De même, pour effectuer une substitution de plage d'adresses, vous pouvez faire quelque chose comme ceci -
$ cat /etc/passwd | sed '1,5s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/quiet
daemon:x:1:1:daemon:/usr/sbin:/bin/quiet
bin:x:2:2:bin:/bin:/bin/quiet
sys:x:3:3:sys:/dev:/bin/quiet
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Comme vous pouvez le voir dans la sortie, les cinq premières lignes avaient la chaîne sh changé en quiet, mais le reste des lignes n'a pas été modifié.
La commande correspondante
Vous utiliseriez le p option avec la -n option pour imprimer toutes les lignes correspondantes comme suit -
$ cat testing | sed -n '/root/p'
root:x:0:0:root user:/root:/bin/sh
[root@ip-72-167-112-17 amrood]# vi testing
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Utilisation d'une expression régulière
Lors de la mise en correspondance de modèles, vous pouvez utiliser l'expression régulière qui offre plus de flexibilité.
Vérifiez l'exemple suivant qui correspond à toutes les lignes commençant par daemon puis les supprime -
$ cat testing | sed '/^daemon/d'
root:x:0:0:root user:/root:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
Voici l'exemple qui supprime toutes les lignes se terminant par sh -
$ cat testing | sed '/sh$/d'
sync:x:4:65534:sync:/bin:/bin/sync
Le tableau suivant répertorie quatre caractères spéciaux très utiles dans les expressions régulières.
Sr.No. | Caractère et description |
---|---|
1 | ^ Correspond au début des lignes |
2 | $ Correspond à la fin des lignes |
3 | . Correspond à n'importe quel caractère |
4 | * Correspond à zéro ou plusieurs occurrences du caractère précédent |
5 | [chars] Correspond à l'un des caractères indiqués dans chars, où chars est une séquence de caractères. Vous pouvez utiliser le caractère - pour indiquer une plage de caractères. |
Personnages correspondants
Regardez quelques expressions supplémentaires pour illustrer l'utilisation de metacharacters. Par exemple, le modèle suivant -
Sr.No. | Expression et description |
---|---|
1 | /a.c/ Correspond aux lignes contenant des chaînes telles que a+c, a-c, abc, match, et a3c |
2 | /a*c/ Correspond aux mêmes chaînes avec des chaînes telles que ace, yacc, et arctic |
3 | /[tT]he/ Correspond à la chaîne The et the |
4 | /^$/ Correspond aux lignes vides |
5 | /^.*$/ Correspond à une ligne entière quelle qu'elle soit |
6 | / */ Correspond à un ou plusieurs espaces |
sept | /^$/ Allumettes blank lignes |
Le tableau suivant montre quelques jeux de caractères fréquemment utilisés -
Sr.No. | Ensemble et description |
---|---|
1 | [a-z] Correspond à une seule lettre minuscule |
2 | [A-Z] Correspond à une seule lettre majuscule |
3 | [a-zA-Z] Correspond à une seule lettre |
4 | [0-9] Correspond à un seul nombre |
5 | [a-zA-Z0-9] Correspond à une seule lettre ou à un chiffre |
Mots-clés de classe de caractère
Certains mots clés spéciaux sont généralement disponibles pour regexps, en particulier les utilitaires GNU qui utilisent regexps. Celles-ci sont très utiles pour les expressions régulières sed car elles simplifient les choses et améliorent la lisibilité.
Par exemple, les personnages a through z et les personnages A through Z, constituent l'une de ces classes de caractères ayant le mot-clé [[:alpha:]]
En utilisant le mot-clé de classe de caractères alphabet, cette commande imprime uniquement ces lignes dans le /etc/syslog.conf fichier commençant par une lettre de l'alphabet -
$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p'
authpriv.* /var/log/secure
mail.* -/var/log/maillog
cron.* /var/log/cron
uucp,news.crit /var/log/spooler
local7.* /var/log/boot.log
Le tableau suivant est une liste complète des mots-clés de classe de caractères disponibles dans GNU sed.
Sr.No. | Classe de personnage et description |
---|---|
1 | [[:alnum:]] Alphanumérique [az AZ 0-9] |
2 | [[:alpha:]] Alphabétique [az AZ] |
3 | [[:blank:]] Caractères vides (espaces ou tabulations) |
4 | [[:cntrl:]] Caractères de contrôle |
5 | [[:digit:]] Numéros [0-9] |
6 | [[:graph:]] Tous les caractères visibles (à l'exclusion des espaces) |
sept | [[:lower:]] Lettres minuscules [az] |
8 | [[:print:]] Caractères imprimables (caractères non contrôlés) |
9 | [[:punct:]] Caractères de ponctuation |
dix | [[:space:]] Espace blanc |
11 | [[:upper:]] Lettres majuscules [AZ] |
12 | [[:xdigit:]] Chiffres hexadécimaux [0-9 af AF] |
Référencement Aampersand
le sed metacharacter &représente le contenu du modèle correspondant. Par exemple, disons que vous avez un fichier appeléphone.txt plein de numéros de téléphone, tels que les suivants -
5555551212
5555551213
5555551214
6665551215
6665551216
7775551217
Vous voulez faire le area code(les trois premiers chiffres) entourés de parenthèses pour une lecture plus facile. Pour ce faire, vous pouvez utiliser le caractère de remplacement esperluette -
$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt
(555)5551212
(555)5551213
(555)5551214
(666)5551215
(666)5551216
(777)5551217
Ici, dans la partie du motif, vous faites correspondre les 3 premiers chiffres, puis utilisez & vous remplacez ces 3 chiffres par les parentheses.
Utilisation de plusieurs commandes sed
Vous pouvez utiliser plusieurs commandes sed dans une seule commande sed comme suit -
$ sed -e 'command1' -e 'command2' ... -e 'commandN' files
Ici command1 à travers commandNsont des commandes sed du type décrit précédemment. Ces commandes sont appliquées à chacune des lignes de la liste des fichiers donnée par les fichiers.
En utilisant le même mécanisme, nous pouvons écrire l'exemple de numéro de téléphone ci-dessus comme suit -
$ sed -e 's/^[[:digit:]]\{3\}/(&)/g' \
-e 's/)[[:digit:]]\{3\}/&-/g' phone.txt
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217
Note - Dans l'exemple ci-dessus, au lieu de répéter le mot-clé de la classe de caractères [[:digit:]] trois fois, nous l'avons remplacé par \{3\}, ce qui signifie que l'expression régulière précédente est mise en correspondance trois fois. Nous avons également utilisé\ pour donner un saut de ligne et cela doit être supprimé avant que la commande ne soit exécutée.
Références arrière
le ampersand metacharacterest utile, mais encore plus utile est la possibilité de définir des régions spécifiques dans les expressions régulières. Ces régions spéciales peuvent être utilisées comme référence dans vos chaînes de remplacement. En définissant des parties spécifiques d'une expression régulière, vous pouvez ensuite faire référence à ces parties avec un caractère de référence spécial.
Faire back references, vous devez d'abord définir une région, puis vous référer à cette région. Pour définir une région, vous insérezbackslashed parenthesesautour de chaque région d'intérêt. La première région que vous entourez de barres obliques inverses est ensuite référencée par\1, la deuxième région par \2, etc.
En supposant phone.txt contient le texte suivant -
(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217
Essayez la commande suivante -
$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \
code: \1 Second: \2 Third: \3/'
Area code: (555) Second: 555- Third: 1212
Area code: (555) Second: 555- Third: 1213
Area code: (555) Second: 555- Third: 1214
Area code: (666) Second: 555- Third: 1215
Area code: (666) Second: 555- Third: 1216
Area code: (777) Second: 555- Third: 1217
Note - Dans l'exemple ci-dessus, chaque expression régulière entre parenthèses serait référencée à nouveau par \1, \2etc. Nous avons utilisé\pour donner un saut de ligne ici. Cela doit être supprimé avant d'exécuter la commande.