Traitement textuel
BRE vs ERE
Avant d'aborder les commandes sed et awk, voici un tableau qui récapitule les marqueurs utilisables dans les expressions régulières basic (Basir Regular Expression) et dans les expressions régulières étendu (Extended Regular Expression) :
| Marqueur | Signification | BRE | ERE |
|---|---|---|---|
| . | tous caractère (une fois) | ✓ | ✓ |
| [] | classe de caractères | ✓ | ✓ |
| ^, $ | début de ligne, fin de ligne | ✓ | ✓ |
| () | fenêtre de capture | ✓ | ✓ |
| * | 0 ou n caractères | ✓ | ✓ |
| {} | X caractères ou X,Y caractères | ✓ | ✓ |
| + | 1 ou n caractères | ✓ | |
| ? | 0 ou 1 caractère | ✓ | |
| regex1|regex2 | regex1 ou regex2 | ✓ |
sed
Sed utilise par défaut les expressions régulières BRE.
Utilisation :
Sed peut être utilisé directement sur un fichier ou derrière un tuyau (pipe) pour filter les résultats d'une autre commande. Les instructions peuvent être sauvegardé dans un fichier passe ensuite à la commande sed via le switch -f
sed 'instructions' fichier
commande | sed 'instructions'
sed -f instructions.sed fichier
Les instructions peuvent également constituer un script à part entière en utilisant le marqueur de début de fichier suivant :
#! /usr/bin/sed -f
instructions
Switch
- -i, inline, traite le fichier sur place (sinon, le fichier n'est pas modifié)
- -n, not, n'affiche pas toutes les lignes
Instructions
- p → print
- d → delete
- s → substitue
Sélection
- Rien : toutes les lignes
- N° de ligne : 1 3 17 ou $ → dernière ligne
- Série de ligne : 17,$ → de,à
- /regex/ : expression régulière BRE
- /regex1/,/regex2/ : de regex1 à regex2
Regex
Attention, le shell interprète les parenthèse () et les accolades {}. Il faut les échaper avec des antislashs \.
Les fenêtres de captures (parenthèses) sont récupérées via des \num comme \1 ou \3
Exemples
sed 's/bla/bli/' # remplace la première occurence de bla par bli
sed 's/bla/bli/g' # remplace toutes les occurances de bla par bli
sed -n '17p' # affiche la 17ème ligne
sed '3,17d' # supprime les lignes entre la 3ème et la 17ème ligne
sed '3d;17d' # supprime la ligne 3 puis la ligne 17
sed '/^[[:blank:]]*$/d' # supprime les lignes vides
sed '3,17 { s/bla/bli/g; /^[[:blank:]]*$/d }' # entre les 3ème et 17ème lignes, remplace bla par bli et supprime les lignes vides.
awk
AWK utilise par défaut des expressions régulières ERE.
Utilisation :
Comme sed, awk peut être utilisé directement sur un fichier ou derrière un tuyau (pipe) pour filter les résultats d'une autre commande. Les instructions peuvent être sauvegardé dans un fichier passe ensuite à la commande awk via le switch -f
awk 'instructions' fichier
command | awk 'instructions'
awk -f instruction.awk fichier
Toujours comme sed, les instructions peuvent constituer un script à part entière en utilisant le marqueur de début de fichier suivant :
\#! /usr/bin/awk -f
instructions
Structure de commande
Une commande awk se structure généralement comme suis :
awk 'selection { commandes }'
Il est possible d'indiquer que des instructions doivent s'exécuter avant et après le traitement :
awk 'BEGIN { commandes_avant }; selection1 { commandes_pendant1 }; selection2 { commandes_pendant2 }; END { commandes_après }'
Notion d'enregistrement et de champs
Awk découpe automatiquement le contenu en enregistrements. Par défaut, les enregistrements sont séparés par les retour à la ligne (RS pour Record Separator est égal à \n). Autrement dit, awk voit chaque ligne comme un enregistrement. Ces derniers sont ensuite découpé en champs et la valeur de chaque champs est placé dans des variables : $1, $2, $3, etc. La séparation des champs (FS pour Field Separator) se fait par défaut avec les espaces et les tabulations.
Sélection :
rien ou /regex/
Commandes :
- print → affiche une donnée (autorise \n, \t, …). Par défaut, chaque donnée est séparée de la suivante par un espaces
- if, else if, else → établir des conditions (syntax du C/C++)
- while, for, break → boucles (syntax du C/C++)
- next → passer à l'enregistrement suivant
Variables
- NF → number field, nombre de champs (dans un enregistrement)
- NR → number record, nombre d'enregistrements
- FS → field separator, séparateur de champ (en entrée)
- RS → record separator, séparateur d'enregistrement (en entrée)
- OFS → output field separator, séparateur de champ (en sortie)
- ORS → output rrecord separator, séparateur d'enregistrement (en sortie)
Opérateurs :
- == → égal à
- != → différent
- < → inférieur
- <= → inférieur ou égal
- > → supérieur
- >= → supérieur ou égal
- ~ → égal à regex
- !~ → différent de regex
- || → ou
- && → et
- var=val → affectation de valeur
- +, -, *, /, % → opérations
- var++, var--, var+=X, *var=Y**, … → incrémentations
Exemples :
Voici quelques exemples pour tester awk :
# Exemple 1 :
awk 'BEGIN { FS=":" }; $3 >= 1000 { print $3, $1; nb++ }; END { print nb, "UID sont > à 1000" }' /etc/passwd
# Exemple 2 :
printf "bla,bli,blo\ngna,gni,gno\ngla,gli,glo" | awk 'BEGIN { FS="," ; RS="\n" ; OFS="\n" ; ORS="\n\n" } { print "1 → "$3, "2 → "$2 }'
# Exemple 3 :
echo "$PATH" | awk 'BEGIN { RS=":" }; { print "⋅ "$1 }'
# Exemple 4 :
awk 'BEGIN { FS=":" } { env[$7]++ } END { for (e in env) print env[e]" × "e; }' /etc/passwd
# Exemple 5 :
ps ux | awk '{print $6, $5, $11}' | sort -rnt ' ' | less
En vous aidant de la documentation officiel d'awk, essayer de comprendre de façon exhaustive chacun des exemples ci-dessus.
