Sed et Awk sont deux outils de textprocessing, invoqués de la même manière :
command [options] script filename
Comme la plupart des programmes UNIX, sed et awk peuvent lire sur l'entrée standard et écrire sur la sortie standard, mais aussi recevoir un flux de données depuis un fichier, et bien sûr rediriger les sorties vers un fichier.
Le script spécifie les intructions à exécuter, et doit être quoté
(encadré d'apostrophes) si il est directement codé sur la ligne de
commande. Une option est commune à awk et
sed, -f , qui permet de spécifier un
script externe.
sed -f scriptfile inputfile
La figure ci-dessous montre le fonctionnement de base de sed et awk. Chaque programme lit ligne par ligne le fichier d'entrée, en fait une copie, et exécute les instructions prévues dans le script sur cette copie. Les changement n'affectent pas le fichier source.
Commande de substitution
La commande s permet d'effectuer des substitutions suivant la syntaxe : sed -e 's/expr-régulière/remplacement/options'
Options
Sans précision, la commande ne s'applique qu'à la 1ère occurence de chaque ligne
0...9: indique que la substitution ne s'applique qu'à la nième occurenceg: effectue les modifications sur toutes les occurences trouvées
Exemple : sed -e 's/moi/toi/g' fich.moi > fich.toi le fichier fich.moi est parcouru, à chaque occurrence de "moi", ce mot est remplcé par "toi" et le nouveau fichier est sauvegardé sous le nom fich.toi
Destruction ou sélection
Cette option permet de filtrer les lignes qui satisfont une expression régulière. Ces lignes ne sont pas détruites dans le fichier d'origine, mais ne sont pas transmise en sortie.
Par exemple, pour détruire toutes les lignes vide d'un fichier : sed -e '/^$/d'
Ajout, insertion et modification
Pour utiliser ces commandes, il est nécessaire de les saisir sur plusieurs lignes
sed [adresse] commande\ expression
La commande peut être :
a pour ajout ;
i pour insertion ;
c pour modification
Exemple :
/<Neotech 3>/i\ CPEN GREATTA - NEOTECH 3\ Cité scolaire du butor
Exemple : supprimer les lignes commençant par un commentaire dans
le fichier suivant : /etc/hosts
EXEMPLE :
$ sed -e '/^#/d' /etc/hosts > ~/myhosts
Le fichier résultant est nommé
~/myhosts. L'expression utilisée est vraie pour
toute chaîne commençant par le caractère # (marque de commentaire dans
un fichier).
Remplacer toutes les occurences de l'interface rl0 du fichier
(FreeBSD) /etc/ipf.conf, par
l'interface xl1 :
EXEMPLE :
# sed -e 's/rl0/xl1/g' /etc/ipf.conf > /etc/ipf.conf.new
Le # dénote ici une opération effectuée en tant que super-utilisateur root. L'expression commence par un s, lequel indique une opération de substitution. Le g, quant à lui indique que tous les remplacements sur une ligne doivent être fait, en son abscence seule la première occurence trouvée sur la ligne serait remplacée.
Quelques expressions régulières. Ces exemples montrent l'utilisation d'expressions régulières, nous rappelons dans ce qui suit quelques méta-caractères importants :
Tableau 1. Expressions régulières
| Caractère | Description | Exemple |
|---|---|---|
| ^ | Correspondance avec le début de ligne | /^#/ ligne
commençant par un un #. |
| $ | Correspondance avec la fin de ligne | /^$/ ligne
blanche. |
| . | Correspondance avec un caractère quelconque | /../ ligne contenant
au moins deux caractères quelconques. |
| * | Correspondance avec 0 ou plusieurs caractères quelconques. | /^a*/ ligne
commençant par a suivit par n'importe quoi. |
| [] | Correspondance avec tout caractères de l'intervalle | /[abc]$/ ligne se
terminant par le motif abc. |
Donnons un autre exemple de combinaison d'expressions régulières. On cherche à imprimer (si elle existe) la fonction main d'un script Perl :
EXEMPLE :
$ cd bin ; sed -n -e '/sub[[:space:]]*main[[:space:]]*{/, /^}/p' *.pl | less
La première partie de cette expression régulière
sub[[:space:]]*main[[:space:]]*{ permet
de trouver le début de la définition de la fonction
main, tandis que la seconde
/^}/ trouve la fin du bloc de cette
fonction. La classe spéciale
[[:space:]] permet de dénoter un
caractère espace ou un caractère TAB. Enfin, la commande
p imprime les lignes qui vérifient la
condition.
Quelques classes.
Tableau 2. Expressions régulières
| Classe | Sémantique |
|---|---|
| [:alnum:] | Caractères alphanumérique : [a-zA-Z0-9]. |
| [:alpha:] | Caractères alphabétiques : [a-zA-Z]. |
| [:blank:] | Caractère espace ou tabulation. |
| [:digit:] | Chiffre [0-9]. |
| [:lower:] | Caractères minuscules [a-z]. |
| [:space:] | Espace. |
| [:upper:] | Caractères majuscules [A-Z]. |
| [:cntl:] | Caractère de contrôle. |
| [:graph:] | Caractère visibles (donc sans l'espace). |
| [:print:] | Caractère autres que les caractères de contrôle. |
| [:punct:] | caractères de ponctuation. |
| [:xdigit:] | Chiffres héxadécimaux [0-9a-fA-F]. |
Donnons maintenant un autre exemple faisant intervenir la
mémorisation d'expression. On veut cette fois ci remplacer les
occurences d'adresses IP du fichier /etc/hosts, par
leur adresse dans le domaine in-addr.arpa :
EXEMPLE :
$ awk -F" " '{print $1}' /etc/hosts | sed -e 's/\([[:digit:]]*\)\.\([[:digit:]]*
\)\.\([[:digit:]]*\)\.\([[:digit:]]*\)/arpa.in-addr.\3.\2.\1/' -e '/^#/d'
arpa.in-addr.200.168.192
arpa.in-addr.200.168.192
arpa.in-addr.1.168.192
arpa.in-addr.1.168.192
On utilise maintenant les parenthèses de mémorisation, autour de classes. L'opérateur * permet d'attendre plusieurs chiffres. On reconnaît l'expression qui permet de filtrer les adresses IPv4. L'expression \3 dénote la troisième expression mémorisée i.e. le troisième octet, tandis que \2 désigne la deuxième expression...
On peut combiner les instructions, il suffit pour cela de rajouter
autant d'option -e que nécessaire. Si cela devient trop
complexe, on peut tout placer dans un fichier et l'appeler au besoin
avec l'option -f.
Il est possible d'effectuer plusieurs transformations sur la même région (zone dénotée par un début et une fin : étiquettes ou numéro de lignes). Dans l'exemple qui suit nous proposons de transformer certains termes dans une région dont le début est marquée par une ligne commençant par le mot BEGIN et se terminant par le mot END (ou la fin de fichier si ce mot n'est pas trouvé).
EXEMPLE : # # ~/mycommand.sed # /^BEGIN/, /^END/ { s/[Ll]inux/GNU\/Linux/g s/[Oo]penbsd/OpenBSD/g s/[Ff]reebsd/FreeBSD/g s/[Nn]etBSD/NetBSD/g } USAGE : $ sed -n -f ~/mycommand.sed myfile.txt > res.txt
Créez un nouveau répertoire
~/elementBase/part3/. Copiez y le fichier
ps-aux que nous avions utilisé lors de la
dernière séance.
Travail à faire.
Supprimer les processus dont le propriétaire est root, et placez le résultat dans
my_ps-auxModifiez le nom du propriétaire sysop, en le remplaçant par le votre. Le résultat est placé dans
my_ps-auxSupprimez les éventuels chemins des exécutables. (
/bin/tcshdeviendratcsh)
On dispose d'un répertoire web contenant des fichiers html, pour lesquels on voudrait changer toutes les occurences des images au format gif par des images identiques au format png.
Travail à faire. Proposer un script qui effectue ces changements dans tous les fichiers. On sauvegardera de plus tous les anciens fichiers dans un sous-repértoire nommé BAK.
Proposition de correction. On se place dans le repertoire cible.
SCRIPT SHELL (sh) :
if [ ! -d BAK ]; then mkdir BAK; fi && \
for f in `find . -name "*.htm[l]" -print`; do
cp $f BAK
sed -e 's/.gif/.png/g' < $f > $f.tmp
mv $f.tmp $f
done
