ENSI-II2 Environnement Unix
Partie I : AWK Exercice 1 Question 1 - Afficher la nième ligne d'un fichier Pour afficher une ligne spécifique (par exemple, la 5ème ligne), nous utilisons la variable interne NR (Number of Record) qui stocke le numéro de la ligne courante.
D'après le document ENSI-II2 Environnement Unix
Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source
Programming, Unix, AWK, SED · PDF · 4 pages
Afficher l'aperçu du document
Partie I : AWK
Exercice 1
Question 1 - Afficher la nième ligne d'un fichier
Pour afficher une ligne spécifique (par exemple, la 5ème ligne), nous utilisons la variable interne NR (Number of Record) qui stocke le numéro de la ligne courante.
awk 'NR == 5' fichier
Question 2 - Compter le nombre de mots d'un fichier
La variable interne NF (Number of Fields) contient le nombre de champs (mots par défaut) de la ligne courante. Nous pouvons les additionner dans une variable et afficher le total à la fin.
awk '{ mots += NF } END { print mots }' fichier
Question 3 - Afficher les lignes de plus de 80 caractères
La fonction length($0) renvoie la longueur totale de la ligne courante. L'action par défaut d'awk étant d'afficher la ligne (print), il suffit de définir la condition.
awk 'length($0) > 80' fichier
Question 4 - Afficher les lignes qui contiennent exactement deux champs
Nous utilisons à nouveau la variable NF en la comparant avec la valeur 2.
awk 'NF == 2' fichier
Question 5 - Afficher la liste des champs de chaque ligne dans un ordre inversé
Il faut parcourir les champs de chaque ligne en partant du dernier (NF) jusqu'au premier (1), en utilisant la fonction printf pour éviter les retours à la ligne après chaque champ, puis afficher un saut de ligne avec print "".
awk '{
for (i = NF; i > 0; i--) {
printf "%s ", $i
}
print ""
}' fichier
Question 6 - Compter le nombre de lignes qui contiennent la chaîne "l2ti"
Nous incrémentons une variable à chaque fois que la chaîne correspond à l'expression régulière /l2ti/. Le +0 dans le bloc END garantit l'affichage de 0 si aucune ligne ne correspond (au lieu d'un affichage vide).
awk '/l2ti/ { count++ } END { print count+0 }' fichier
Question 7 - Afficher toutes les lignes dont le premier champ est différent de celui de la ligne précédente
Nous comparons le premier champ $1 avec une variable qui stocke le premier champ de la ligne précédente. Si c'est différent, nous affichons la ligne, puis nous mettons à jour la variable.
awk '$1 != prev { print } { prev = $1 }' fichier
Exercice 2 - Mots avec trois lettres majuscules adjacentes ou plus
L'énoncé demande d'afficher les mots. Il faut donc examiner chaque champ de chaque ligne. L'expression régulière /[A-Z][A-Z][A-Z]/ vérifie la présence d'au moins trois majuscules consécutives.
#!/usr/bin/awk -f
{
for (i = 1; i <= NF; i++) {
if ($i ~ /[A-Z][A-Z][A-Z]/) {
print $i
}
}
}
Exercice 3 - Fichiers accédés uniquement en lecture par les autres utilisateurs
Pour obtenir les permissions, nous couplons awk à la commande ls -l. Le motif des permissions correspond à 10 caractères. "Uniquement en lecture par les autres" signifie que les 8ème, 9ème et 10ème caractères doivent être r, - et -.
ls -l | awk '/^.......r--/ { print $9 }'
Note : Le 9ème champ ($9) correspond au nom du fichier dans la sortie standard de ls -l sur la plupart des systèmes Unix.
Exercice 4 - Dates de connexion des propriétaires des fichiers portant la permission de lecture pour les autres
La permission "lecture pour les autres" signifie que le 8ème caractère des droits est un r. Le propriétaire se trouve dans le 3ème champ ($3). Nous mémorisons les propriétaires vus dans un tableau vu pour ne pas lancer la commande last plusieurs fois pour le même utilisateur. La fonction system() permet à awk d'exécuter une commande shell.
ls -l | awk '/^.......r../ {
if (!vu[$3]++) {
system("last " $3)
}
}'
Exercice 5 - Lignes dont le premier champ est différent de celui de la ligne précédente
Cette question est une répétition exacte de l'Exercice 1, Question 7 du sujet source. La commande est strictement la même :
awk '$1 != prev { print } { prev = $1 }' fichier
Exercice 6 - Simuler la commande "uniq" en éliminant les lignes redondantes et vides
La commande classique uniq ne filtre que les doublons adjacents. La question ajoute également l'élimination des lignes vides (NF == 0).
#!/usr/bin/awk -f
# On ignore les lignes vides
NF == 0 { next }
# Si la ligne entière ($0) est différente de la précédente, on l'affiche
$0 != prev {
print $0
prev = $0
}
Alternative : Si l'énoncé sous-entendait une suppression globale des doublons (peu importe leur position dans le fichier), le code court classique serait : awk 'NF > 0 && !vu[$0]++' fichier.
Exercice 7 - Vérification du nombre de champs par enregistrement
Le script doit définir : comme séparateur, lire le nombre de champs de la première ligne, puis comparer chaque ligne suivante à cette référence.
Fichier count.awk :
BEGIN {
FS = ":"
erreurs = 0
}
# Traitement de la toute première ligne
NR == 1 {
attendu = NF
print "Chaque enregistrement doit comporter " attendu " champs"
}
# Traitement de toutes les lignes (y compris la première, qui passera forcément ce test)
{
if (NF != attendu) {
print "Enregistrement " NR " a " NF " champs"
erreurs++
}
}
# Traitement à la fin du fichier
END {
print "Le fichier " FILENAME " possède " NR " enregistrements"
if (erreurs > 0) {
print "Le fichier " FILENAME " comporte " erreurs " enregistrement(s) erroné(s)"
} else {
print "Tous les enregistrements sont corrects."
}
}
Exécution : awk -f count.awk test ou awk -f count.awk /etc/passwd produira exactement la sortie demandée par l'énoncé.
Partie II : SED
Question 1 - Afficher des lignes contenant trois majuscules successives
L'option -n supprime l'affichage par défaut de sed, et la commande p force l'affichage uniquement pour les lignes validant le motif.
sed -n '/[A-Z]\{3\}/p' fichier
Note : /[A-Z][A-Z][A-Z]/ est également correct.
Question 2 - Remplacer les mots Computer ou comuter par COMPUTER
Nous respectons l'orthographe de la source (le mot "comuter" est explicitement mentionné). Le drapeau g à la fin indique un remplacement global sur toute la ligne.
sed 's/\(Computer\|comuter\)/COMPUTER/g' fichier
Question 3 - Encadrer le premier nombre de chaque ligne avec des **
Un nombre s'exprime par une série de chiffres : [0-9]\+ ou [0-9][0-9]*. Le symbole & dans la zone de remplacement fait référence à la chaîne qui a été trouvée. Sans le drapeau g, seul le premier nombre de la ligne est impacté.
sed 's/[0-9][0-9]*/**&**/' fichier
Question 4 - Afficher un fichier à partir de la onzième ligne
L'intervalle de lignes 11,$ désigne la 11ème ligne jusqu'à la fin ($) du fichier. L'option -n et la commande p n'affichent que cette zone.
sed -n '11,$p' fichier
Question 5 - Imprimer les lignes commençant par le mot From
L'accent circonflexe ^ sert d'ancre pour désigner le début de la ligne.
sed -n '/^From/p' fichier
Question 6 - Supprimer les lignes contenant une chaîne donnée
La commande d sert à détruire (supprimer) l'espace de travail pour la ligne courante correspondant au motif. Remplaçons "chaine" par le texte désiré.
sed '/chaine/d' fichier
Question 7 - Supprimer les lignes ne contenant pas une chaîne donnée
Le point d'exclamation ! permet d'inverser la logique d'une commande. Ici, il applique la commande de suppression (d) à toutes les lignes ne validant pas le motif.
sed '/chaine/!d' fichier
Question 8 - Significations des commandes de remplacement
sed "s/toto/TOTO/" fichierRemplace uniquement la première occurrence de la chaîne "toto" par "TOTO" sur chaque ligne parcourue.sed "s/toto/TOTO/3" fichierRemplace spécifiquement la troisième occurrence de la chaîne "toto" par "TOTO" sur chaque ligne (les 1ère et 2ème restent intactes).sed "s/toto/TOTO/g" fichierRemplace toutes les occurrences ("g" pour global) de la chaîne "toto" par "TOTO" sur toute la ligne.sed "s/toto/TOTO/w resultat" fichierRemplace la première occurrence de "toto" par "TOTO" sur chaque ligne et écrit (sauvegarde) spécifiquement les lignes qui ont subi une modification dans le fichier externe nomméresultat, tout en continuant d'afficher la sortie standard.
Question 9 - Inverser l'ordre de la première et la deuxième colonne d'un fichier
Nous utilisons les parenthèses capturantes \( et \) pour conserver les colonnes, et \1 et \2 pour les rappeler. En supposant que les colonnes soient séparées par des espaces ou tabulations ([^ \t]\+ représente un bloc de texte sans espace).
sed 's/^\([^ \t]\+\)\([ \t]\+\)\([^ \t]\+\)/\3\2\1/' fichier
Note : Une version simplifiée considérant de simples espaces serait : sed 's/^\([^ ]*\) *\([^ ]*\)/\2 \1/' fichier
Question 10 - Entourer chaque nombre contenu dans un fichier par deux a
Comme pour la question 3, & représente le nombre trouvé. L'ajout de g force sed à faire le remplacement sur tous les nombres de la ligne, et non juste le premier.
sed 's/[0-9][0-9]*/a&a/g' fichier
Question 11 - N'afficher que les lignes contenant le nombre 55 d'un fichier donné
Pour s'assurer d'avoir le nombre 55 strict (et ne pas déclencher sur 155 ou 555), il est recommandé d'utiliser des frontières de mots \b.
sed -n '/\b55\b/p' fichier
Si l'enseignant attend la version sed basique sans contrainte de mot, la syntaxe classique est : sed -n '/55/p' fichier.
Méthode
Face à ce type de sujet évaluant la maîtrise d'outils d'extraction textuelle comme awk et sed, voici l'approche à adopter :
- Distinguer la portée du filtre : Demandez-vous toujours si l'opération doit s'appliquer à l'ensemble du fichier (remplacement global : drapeau
gpour sed, boucleforpour awk) ou uniquement au premier élément d'une ligne. - Identifier l'outil optimal :
sedest idéal pour les substitutions (s/.../.../) et les affichages ou suppressions simples basés sur un contexte de ligne entière (/motif/d,11,$p).awkbrille dès qu'il est question de colonnes (champs délimités) et d'arithmétique (comptage de mots avecNF, suivi de variablescount, manipulations de variables internes).
- Comprendre les structures implicites : En
awk, une instruction structurée commecondition { action }applique l'action à chaque ligne vérifiant la condition. S'il n'y a pas d'action (ex :awk 'length($0) > 80'), l'action par défaut est toujours l'affichage de la ligne courante ({ print }). - Maîtriser les regex classiques : Il est impératif de connaître le fonctionnement des classes (
[A-Z],[0-9]), des quantificateurs (*,\+,\{3\}) et des ancres (^pour début de ligne). La justesse de vos scripts dépend de la précision de vos expressions régulières.
Commentaires
Aucun commentaire pour le moment. Posez la première question.