Vous êtes sur la page 1sur 19

Correction du TE 3

Redirections, tubes et filtres

Références
– Polycopié unix : chapitres (4), 5, (6), 7, 8, 9, 10
– Transparents unix : sections 4.3, (7), 8, 9 à 13

Créer un répertoire te3 sous votre répertoire ~/mni/unix : on y placera tous les fichiers de travail du TE3.
En particulier, on y copiera tous les fichiers utiles fournis dans le répertoire te3 du compte de l’UE.

Ex. 1 : Rappels sur le TE précédent A 12 min.


Répondre brièvement aux questions ci-dessous sur une feuille à part, sans l’aide de document ou de
l’ordinateur.
1. À partir de votre répertoire d’accueil, placez-vous dans le répertoire te2, situé dans le répertoire
~/mni/unix.

Solution
cd mni/unix/te2
2. Sans changer de répertoire de travail, listez le contenu du répertoire M1 qui se trouve dans le
répertoire d’accueil de l’utilisateur lefrere.

Solution
ls ~lefrere/M1
3. Que font chacune des commandes suivantes ?
cd ; cd ~ ; cd .. ; cd /

Solution
Respectivement : aller dans le répertoire d’accueil (pour les deux premières), dans le répertoire
parent du répertoire courant, et aller à la racine du système.
4. Copiez le fichier ~lefrere/M1/foo.bar dans votre répertoire unix/te2

Solution
cp ~lefrere/M1/foo.bar ~/mni/unix/te2
5. À partir de votre répertoire d’accueil, donnez la commande permettant de renommer un fichier
foo.bar situé dans le répertoire ~/mni/unix/te2 en hello.txt (sans le changer de répertoire).

Solution
mv ~/mni/unix/te2/foo.bar ~/mni/unix/te2/hello.txt
6. Créez le répertoire ~/mni-test puis déplacez-le dans votre répertoire unix.

Solution
mkdir ~/mni-test ; mv ~/mni-test ~/mni/unix/
7. Listez les fichiers dont l’extension est .txt et qui sont situés dans votre répertoire te2, en affichant
leurs attributs (taille, droits d’accès, ...).

Solution
ls -l ~/mni/unix/te2/*.txt

16
UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

8. Quelle est la commande qui permet de localiser tous les fichiers toto.txt dans l’arborescence sous
votre répertoire d’accueil ?

Solution
find ~/ -name toto.txt -print
9. À la commande ls -l ~lefrere/M1/toto.out, vous obtenez la réponse suivante :
-rw-rw-r-- 1 lefrere personnel 4886 oct 1 2007 toto.out
Vous faites partie du groupe « etudiant ».
Pouvez-vous lire ce fichier ? Le modifier ? Le copier dans votre répertoire d’accueil ?

Solution
Ce fichier est lisible et modifiable par le propriétaire (lefrere), le groupe « personnel », et
uniquement lisible pour les autres utilisateurs. Faisant partie du groupe « etudiant », vous pouvez
donc le lire et le copier dans votre répertoire d’accueil, mais vous ne pouvez le modifier.
10. Dans un répertoire, on dispose d’une série de 9 fichiers nommés ftn.n où n est un entier qui
varie de 1 à 9. Comment supprimer les 7 fichiers ftn.2 à ftn.8 en une seule commande à un seul
argument sans risquer d’en détruire d’autres (ftn.1 ou ftn.f90 par exemple) ?

Solution

rm ftn.[2-8]

11. Indiquer les trois fonctions principales de la commande tar en précisant l’option associée à chaque
fonction.

Solution
création d’archive (c)
liste du contenu d’une archive (t)
extraction de l’arborescence (x)

Ex. 2 : Redirections de sortie A 10 min.


Choisir ~/mni/unix/te3 comme répertoire de travail. Écrire la suite de commandes unix qui créent un
fichier memo contenant la date, le nom de la machine, votre login, tels que fournis par le système, et le
mot du jour de l’UE (~lefrere/M1/Config/motd 1 ).
Sans utiliser d’éditeur de texte, ajouter le texte « fin du memo » à la fin de ce fichier.
Solution

#!/bin/sh
# fichier redir-out.sh
# le 20/09/2002
date > memo
hostname >> memo
whoami >> memo
cat /etc/motd >> memo
echo fin du memo >> memo
exit

Ex. 3 : Sortie standard et sortie d’erreur standard A 10 min.


Tester les commandes suivantes et expliquer le contenu des fichiers créés :
1. cat /home/lefrere/M1/Config/motd > log1
more log1
1. Le mot du jour d’une machine unix est en principe géré par l’administrateur et stocké dans le fichier /etc/motd. Dans
le cas de la machine virtuelle utilisée à l’utes, on utilisera le mot du jour de l’UE ~lefrere/M1/Config/motd.

2011–2012 17 29 septembre 2011 v.473/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

2. cat /inexistant > log1


more log1
cat /inexistant 2> log2
more log2
3. cat /home/lefrere/M1/Config/motd /inexistant > log1 2> log2
cat log1
more log2
4. cat /home/lefrere/M1/Config/motd /inexistant > log 2>&1
more log

Ex. 4 : Utilisation du filtre tr AB 15 min.


Recopier dans votre répertoire de travail le fichier
~lefrere/M1/2011-2012/etu/mni/unix/te/te3/ligne-ascii.txt
puis tester et expliquer le comportement des commandes suivantes (s’aider du manuel en ligne de tr) :

1 cat ligne-ascii.txt
2 tr aeiou AEIOU < ligne-ascii.txt
3 tr aeiou AEIOU < ligne-ascii.txt > LIGNE-ascii.txt
4 cat LIGNE-ascii.txt
5 cat ligne-ascii.txt | tr aeiou AEIOU
6 tr ’0123456789’ ’abcdefghij’ < ligne-ascii.txt
7 tr ’0-9’ ’a-j’ < ligne-ascii.txt
8 tr "[:lower:]" "[:upper:]" < ligne-ascii.txt
9 tr "a-z" "A-Z" < ligne-ascii.txt
10 tr ’0-9’ ’+’ < ligne-ascii.txt
11

12 tr -d ’a-d’ < ligne-ascii.txt


13 echo ’1a2aa3aaa4bbbb’ | tr ’a’ ’A’
14 echo ’1a2aa3aaa4bbbb’ | tr -s ’a’ ’A’
15 echo ’1a2aa3aaa4bbbb’ | tr -s ’a’ ’\n’

Solution
Dans l’ordre :
cat ligne-ascii.txt donne
abcdefghijklmnopqrstuvwxyz azerty 01234567890123
tr aeiuo AEIOU < ligne-ascii.txt ainsi que cat LIGNE-ascii.txt donnent
AbcdEfghIjklmnOpqrstUvwxyz AzErty 01234567890123
tr ’0123456789’ ’abcdefghij’ < ligne-ascii.txt
et tr ’0-9’ ’a-j’ < ligne-ascii.txt donnent
abcdefghijklmnopqrstuvwxyz azerty abcdefghijabcd
tr "[:lower:]" "[:upper:]" < ligne-ascii.txt
et tr "a-z" "A-Z" < ligne-ascii.txt donnent
ABCDEFGHIJKLMNOPQRSTUVWXYZ AZERTY 01234567890123
tr ’0-9’ ’+’ < ligne-ascii.txt donne
abcdefghijklmnopqrstuvwxyz azerty ++++++++++++++

tr -d ’a-d’ < ligne-ascii.txt donne


efghijklmnopqrstuvwxyz zerty 01234567890123
echo ’1a2aa3aaa4bbbb’ | tr ’a’ ’A’ donne
1A2AA3AAA4bbbb
echo ’1a2aa3aaa4bbbb’ | tr -s ’a’ ’A’ donne
1A2A3A4bbbb
echo ’1a2aa3aaa4bbbb’ | tr -s ’a’ ’\n’ donne
1
2
3
4bbbb

29 septembre 2011 v.473/473 18 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

Septembre 2008 avec mandriva 2007.1 en UTF-8 que ne gère pas tr : une version simplifiée sans caractères
accentués permet d’éviter les problèmes de codages ISO-8859/UTF-8. Mais on peut proposer de traiter
les caractères accentués par un contournement avec passage en ISO-8859-1 qui, lui, est très bien compris
par tr à condition de positionner les locales correctement. Par exemple :
echo éàç | \
iconv -f UTF-8 -t ISO-8859-1 | \
LC_ALL=fr_FR.ISO-8859-1 tr ’[[:lower:]]’ ’[[:upper:]]’ | \
iconv -f ISO-8859-1 -t UTF-8
On remarque que les caractères accentués situés après l’ascii standard dans l’ordre lexicographique ne
sont pas inclus dans l’intervalle a-z.

Problèmes de portabilité avec tr


Voir les tests ci-après :
Portabilité de "tr" entre linux, dec-osf1 et aix. J. Lefrère 04/04/2001

Pour des raisons historiques (bsd et SV), on trouve sur les systèmes:
- osf1 et aix : deux commandes "tr" (SV) et "trbsd" (bsd)
- linux : la commande "tr" avec une option supplémentaire "-t"
Pour la commande "trbsd" les crochets ne sont jamais considérés comme spéciaux
et les classes "[:alpha:]" ou les équivalences "[=e=]" sont inconnues;
si l’ensemble des caractères par lesquels on traduit est plus petit que celui
des caractères à traduire, il y a duplication automatique du dernier caractère
pour aboutir à deux ensembles de même longueur.
Cette duplication automatique fonctionne aussi par défaut sous linux
avec le commande "tr".
Au contraire, avec la commande "tr" sous osf1 et aix ou "tr -t" sous linux,
si l’ensemble d’arrivée comporte moins de caractères que celui de départ,
il y a troncature de celui de départ: il n’y a pas duplication automatique.

En résumé, il faut donc comparer "tr -t" sous linux avec "tr" osf1 ou aix
et "tr" sous linux avec "trbsd" sous osf1 et aix.
De plus, avec "tr" sous linux et "trbsd" les crochets "[]" sont des
caractères normaux... mais bien sûr s’ils sont présents des deux côtés
ils n’auront aucune influence : tr ’a-z’ ’A-Z’ est identique à
tr ’[a-z]’ ’[A-Z]’

Quand les crochets ont ils un caractère spécial dans la version System V ?
- pour étendre l’ensemble d’arrivée, il faut utiliser le multiplicateur "*"
mais à l’intérieur des crochets.
tr ’a-z’ ’[+*]’ (osf1/aix)
- pour accéder aux classes de caractères et aux classes d’équivalence
tr ’[:lower:]’ ’[:upper:]’ (osf1/aix) minuscules -> majuscules
tr ’[=e=]’ ’[e*]’ (osf1/aix) eéèêëEÉÈÊË -> e (si LANG ad hoc)

En conclusion, la version System V, plus riche mais de syntaxe plus lourde


est la commande par défaut, mais sous linux, il faut préciser "tr -t".
Enfin, il vaut mieux éviter les crochets superflus.

Si donc on choisit la version System V


(tr sous osf1/aix et tr -t sous linux)
et si on travaille avec la même variable de langue (C ou français),
on obtient les mêmes résultats (première colonne).
La deuxième colonne met en évidence les différences
entre "tr" linux et "trbsd" osf1/aix.

------------------------------------------------------------------------
Essais effectués avec LC_CTYPE et LC_COLLATE non francisés
------------------------------------------------------------------------
[1] [2]
------------------------------------------------------------------------
tr ’a-z’ ’+’ [abcd0z]
Linux (-t) [+bcd0z] tr [++++0+]
OSF1 [+bcd0z] trbsd [++++0+]
AIX [+bcd0z] trbsd [++++0+]

------------------------------------------------------------------------
tr ’a-z’ ’+*’ [abcd0z]
Linux (-t) [+*cd0z] tr [+***0*]
OSF1 [+*cd0z] trbsd [+***0*]
AIX [+*cd0z] trbsd [+***0*]

------------------------------------------------------------------------

2011–2012 19 29 septembre 2011 v.473/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

tr ’[a-z]’ ’+*’ [abcd0z]


Linux (-t) +*bcd0z] tr +****0**
OSF1 +*bcd0z] trbsd +****0**
AIX +*bcd0z] trbsd +****0**

------------------------------------------------------------------------
tr ’[a-z]’ ’[+*]’ [abcd0z]
Linux (-t) +++++0++ tr +++++0++
OSF1 +++++0++ trbsd [+*]]0]]
AIX +++++0++ trbsd [+*]]0]]

------------------------------------------------------------------------
tr ’a-z’ ’[+*]’ [abcd0z]
Linux (-t) [++++0+] tr [++++0+]
OSF1 [++++0+] trbsd [[+*]0]]
AIX [++++0+] trbsd [[+*]0]]

Ex. 5 : Tubes et filtres (more, less, wc, head, tail, sort, grep) A 25 min.
Pour chaque question de 1 à 7 utiliser une commande de liste via \ls 2 et un tube avec un filtre unix.
1. Afficher la liste des fichiers du répertoire /usr/bin/ en contrôlant le défilement écran par écran
(tester avec more puis avec less).
2. Compter le nombre de fichiers de ce répertoire (wc).
3. Afficher les noms des 8 derniers fichiers de /usr/bin/ (tail)
4. Afficher les noms des 8 premiers fichiers de /usr/bin/ (head)
5. Afficher les noms des fichiers de /usr/bin/ classés par ordre alphabétique inverse (sort).
6. Afficher la liste des fichiers du répertoire ~lefrere/M1/Config/ Compter le nombre des fichiers de
ce répertoire.
7. Afficher la liste des fichiers du répertoire ~lefrere/M1/Config/ avec leurs attributs ; les classer
par ordre de taille décroissante. Compter le nombre de fichiers classés. Pourquoi ne retrouve-t’on
pas le nombre précédent ? Insérer un filtre pour éviter ce problème.
On s’intéresse maintenant à des fichiers d’entête pour le préprocesseur cpp
8. Afficher les lignes du fichier /usr/include/limits.h qui comportent la chaîne MAX (grep). Compter
leur nombre.
9. Afficher les 3 premières lignes du fichier /usr/include/limits.h qui comportent la chaîne MAX.
10. AB Afficher les lignes du fichier /usr/include/limits.h qui comportent à la fois l’instruction
préprocesseur #define en début de ligne (avec un nombre arbitraire de blancs entre # et define)
et la chaîne MAX

Solution

#!/bin/sh
echo liste des fichiers de ’/usr/bin/’
\ls /usr/bin/ | more
# sous linux, on peut utiliser less
echo nombre de fichiers de ’/usr/bin/’
\ls /usr/bin/ | wc -l
\ls /usr/bin/ | awk ’END{print NR}’
echo liste des 8 derniers fichiers de ’/usr/bin/’
\ls /usr/bin/ | tail -n 8
echo liste des 8 premiers fichiers de ’/usr/bin/’
\ls /usr/bin/ | head -n 8
ls /usr/bin/ | awk ’NR<=10’
echo liste des fichiers de ’~lefrere/M1/Config’ et nombre de fichiers
\ls ~lefrere/M1/Config | wc -w
2. La commande \ls invoque la commande native /bin/ls évitant ainsi l’affichage des caractères *, @ ou / en fin de
nom de fichier que provoquerait l’alias sur ls -F.

29 septembre 2011 v.473/473 20 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

\ls ~lefrere/M1/Config | wc -l
echo fichiers de ’~lefrere/M1/Config’ + attributs par ordre de taille décroissante
\ls -l ~lefrere/M1/Config | grep -v ’^total’ | sort -k 5,5nr
echo affichage de la taille et du nom des fichiers de ’~lefrere/M1/Config’
\ls -l ~lefrere/M1/Config | grep -v ’^total’ | awk ’{print $5, $NF}’
\ls -l ~lefrere/M1/Config | awk ’NR > 1 {print $5, $NF}’
echo nombre total d\’octets occupés par les fichiers de ’~lefrere/M1/Config’
\ls -l ~lefrere/M1/Config | grep -v ’^total’ | awk ’{s+=$5} END{print s}’
\ls -l ~lefrere/M1/Config | awk ’NR > 1 {s+=$5} END{print s}’
\ls -l ~lefrere/M1/Config | awk ’NF>=9 {s+=$5} END{print s}’
\ls -l ~lefrere/M1/Config | awk ’$1 != "total" {s+=$5} END{print s}’
#
echo "lignes de /usr/include/limits.h comportant la chaîne MAX"
grep MAX /usr/include/limits.h
echo "leur nombre"
grep MAX /usr/include/limits.h | wc -l
echo "3 premières lignes de /usr/include/limits.h comportant la chaîne MAX"
grep MAX /usr/include/limits.h | head -n 3
echo ’lignes de /usr/include/limits.h comportant ’# define ’ et ’MAX’
grep MAX /usr/include/limits.h | grep ’# *define’

Ex. 6 : Fichier de notes avec awk A 15 min.


notes.txt
Nom Prenom Initiales cc1 cc2 examen oral 2011-2012
Le fichier notes.txt
Legrand Jean JL 10 12 13 14
contient les notes
Dupont Yves YD 9 7 9 12
d’un groupe d’étu-
Durand Claire CD 8 12 11 10
diants, précédées
Lefort Corine CL 15 14 14 12
d’une ligne d’entête.
Duran Alberto AD 14 13 11 09
Utiliser le filtre awk pour :
1. Afficher le fichier notes.txt en permutant les champs Nom et Prenom.
Solution
awk ’{print $2,$1,$3,$4,$5,$6,$7}’ notes.txt
2. Afficher, pour chaque ligne du fichier notes.txt, le numéro de la ligne, le premier champ, le nombre
de champs et le dernier champ. Afficher le nombre de lignes du fichier notes.txt
Solution
awk ’{print NR,$1,NF,$NF}’ notes.txt
3. Extraire du fichier notes.txt les lignes des étudiants sans la ligne d’entête et stocker le résultat
dans le fichier notes.dat avec lequel on travaillera par la suite.
Solution
awk ’NR>1{print $0}’ notes.txt > notes.dat
4. Calculer la moyenne de l’épreuve d’oral pour l’ensemble du groupe d’étudiants et l’afficher.
Solution
awk ’BEGIN{oral=0}{oral=oral+$7}END{print oral/NR}’ notes.dat
5. Calculer la moyenne des notes de l’étudiant dont les initiales sont YD et l’afficher.
Solution
awk ’$3=="YD"{moy=($4+$5+$6+$7)/4}END{print moy}’ notes.dat
6. Afficher la liste des étudiants ayant obtenu une note comprise entre 10 et 14 au premier contrôle
continu et en calculer la moyenne.
Solution
awk ’$4>=10 && $4<=14{print $0;moy+=$4;compteur++}END{print moy/compteur}’ notes.dat

2011–2012 21 29 septembre 2011 v.473/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

Ex. 7 : Manipulation de fichier image en niveaux de gris AB 40 min.


Les fichiers d’image de type pgm en niveaux de gris (portable gray map) peuvent être stockés sous les
formats P2 (ascii) ou P5 (binaire). Mais ils comportent tous une entête de trois lignes en texte ascii
décrivant successivement :
ligne 1) le format de fichier sous la forme P2 dans le cas pgm ascii par exemple
ligne 2) le nombre de colonnes (largeur) et le nombre de lignes (hauteur) de l’image
ligne 3) la valeur maximale du niveau de gris qui représente le blanc
Suivent alors les valeurs des pixels en niveau de gris stockées en ascii pour un fichier de type P2. L’image
est parcourue de gauche à droite et de haut en bas ; le nombre de pixels par ligne du fichier ascii ne
détermine pas la géométrie de l’image, qui est spécifiée dans l’entête.
Le fichier img-asc.pgm, fourni sur le compte de l’UE, est un fichier ascii dans lequel les niveaux de gris
sont des entiers compris entre 0 et 255 (blanc).
premières lignes du fichier img-asc.pgm
1 P2
2 92 124
3 255
4 158 125 133 111 130 140 124 232 255 224 254 255 226 230 226 222 208 194 179 197 144 174 171 162 153 155
5 160 157 158 155 165 173 170 207 237 233 223 216 216 236 250 255 252 242 255 255 248 252 247 253 251 244
6 248 255 254 242 246 242 255 247 255 240 254 255 242 255 255 244 239 214 230 195 223 197 207 202 236 204
7 230 199 238 255 204 172 185 162 217 136 79 57 89 113
8 162 66 102 93 179 188 148 192 177 242 209 198 211 164 225 168 218 131 133 142 182 153 170 144 152 134

Travail sur le fichier img-asc.pgm A


1. Quelle commande permet d’afficher le nombre total de lignes du fichier (et non de l’image) img-asc.pgm ?
2. Quelle commande permet de copier les trois premières lignes du fichier img-asc.pgm dans le fichier
entete.txt ?
3. Extraire la partie du fichier img-asc.pgm qui suit l’entête (soit de la ligne 4 à la fin), pour former
le fichier pixels.txt sur lequel on travaillera dorénavant.

Travail sur le fichier pixels.txt

1. A Quelle commande permet de compter le nombre de pixels de l’image ?


2. AB À l’aide du filtre tr, écrire les valeurs des niveaux de gris des pixels à raison d’un par ligne
dans le fichier listpix.txt

Travail sur le fichier listpix.txt AB


1. Quelle commande permet de vérifier le nombre total de pixels dans le fichier listpix.txt ?
2. Comment compter le nombre de pixels au niveau 200 dans le fichier listpix.txt ? Même question
avec le niveau 20.
3. Comment afficher les valeurs des niveaux de gris par ordre décroissant ?
4. Comment afficher la valeur du niveau de gris du pixel le plus clair ? le plus foncé ?
5. Calculer le niveau de gris moyen de l’image.

#!/bin/sh
# traitement de l’image météo

echo "=> passage en ascii"


pnmtoplainpnm img-bin.pgm > img.pgm
echo "=> nb de lignes"
wc -l img.pgm
echo "=> entete"
head -n 3 img.pgm > entete.txt
echo "=> extraction des pixels" # pas demandé

29 septembre 2011 v.473/473 22 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

tail -n +4 img.pgm > pixels.txt


echo "=> nb de pixels"
cat pixels.txt | wc -w # pour éviter le nom du fichier !
echo "un pixel par ligne" # donné
awk ’{for (i=1; i<=NF; i++) {print $i}}’ pixels.txt> listpix.txt
tr -s ’ ’ ’\n’ < pixels.txt > listpix.txt # option squeeze pour \n multiples
echo "=> nombre de pixels"
wc -l listpix.txt
echo "=> nombre de pixels"
wc -w listpix.txt
echo "=> nombre de fois 200 ?"
grep -c ’^200$’ listpix.txt
grep ’^200$’ listpix.txt | wc -w
awk ’$1==200{n++}END{print n}’ listpix.txt
echo "=> nombre de fois 20 ?"
grep -c ’^20$’ listpix.txt
# attention : grep -c 20 listpix.txt compte aussi 120, 204, ...
# si on part du fichier pixels.txt, il faut parcourir tous les champs
# awk ’BEGIN{s=0} {for (i=1;i<=NF;i++) if ($i == 200) s+=1} END{print s}’
echo "=> niveau le plus élévé"
sort -nr listpix.txt | head -n 1
echo "=> niveau le plus bas"
sort -n listpix.txt | head -n 1
echo "niveau moyen"
awk ’{s+=$1} END{print "niveau de gris moyen ", s/NR}’ listpix.txt

Ex. 8 : Programmes et redirections A 20 min.


Les programmes carre.f90 en fortran et carre.c en C (fournis au TE2) lisent trois nombres fournis au
clavier 3 , calculent leur carré, puis affichent ces carrés.
1. Compiler le programme fortran (g95-mni carre.f90) puis tester le fonctionnement de l’exécutable
a.out ainsi produit. Renommer le fichier exécutable en carre-f.exe.
Solution
program carre
! calcul du carre de trois nombres en fortran
implicit none
real, dimension(3) :: a, a2
read(*,*) a(:) ! lecture
a2(:) = a(:) * a(:) ! calcul
write(*,*) a2(:) ! affichage
end program carre
Le compilateur fortran est g95 sur les linux.
Pour la compilation fortran on utilise deux alias avec des options sévères : g95-mni pour le standard
fortran95 et g2003-mni pour le standard fortran-2003.
2. Compiler le programme C (gcc-mni carre.c) et tester le fonctionnement du nouvel exécutable
a.out. Renommer le fichier exécutable en carre-c.exe.
Solution
#include <stdio.h>
#include <stdlib.h>
/* calcul du carré de trois nombres en C */
3. Attention : contrairement à carre+invite.{c,f90}, ces programmes n’affichent aucun message invitant à saisir les
données d’entrée.

2011–2012 23 29 septembre 2011 v.473/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

int main(void)
{
float a[3], a2[3];
int i;
/* attention : lecture sans contrôle de validité */
for (i=0; i<3; i++)
{
scanf("%f", &a[i]);
}
for (i=0; i<3; i++)
{
a2[i] = a[i] * a[i];
}
for (i=0; i<3; i++)
{
printf("%12.9f ", a2[i]);
/* format fixé pour obtenir le même affichage
* qu’avec le format libre du fortran */
}
printf("\n");
exit(0);
}
3. Les filtres du système unix ne sont pas les seuls à pouvoir utiliser les redirections : les programmes
qui lisent au clavier et écrivent à l’écran acceptent aussi les redirections.
Saisir trois nombres dans le fichier in et faire afficher leurs carrés.

Solution
a.out < in
4. Quelles commandes permettent de stocker les résultats de plusieurs exécutions successives dans
un fichier out. Où est envoyé le message d’erreur dans le cas d’une saisie non numérique avec
l’exécutable fortran ? Comment le stocker dans un fichier nommé erreur ?

Solution
a.out > out
a.out >> out
L’erreur s’affiche à l’écran, sauf si on redirige la sortie d’erreur.
a.out 2> erreur >> out
5. AB Comment calculer les puissances quatrièmes des entrées sans modifier le programme source ?
6. B Comment récupérer aussi les carrés dans un autre fichier ?

Solution
a.out | a.out
Si on souhaite voir le résultat intermédiaire, on peut utiliser la commande tee. tee duplique le flux
d’entrée sur la sortie standard et sur le fichier qui lui est passé en paramètre (un T en termes de
tubes !). En choisissant le fichier spécial /dev/tty (qui représente l’écran), on peut donc afficher le
flux passé en pipe :
a.out | tee /dev/tty | a.out
De même, si on calcule les puissances huit des entrées, les résultats intermédiaires, puissances 2 et
4, peuvent être interceptés dans un fichier grâce à l’option -a (append) de tee.
a.out | tee interm | a.out | tee -a interm | a.out

Ex. 9 : Image bitmap (éditeur interactif, sed et tr) AB 20 min.


Le fichier texte esperluette.pbm est une image du caractère & en noir sur fond blanc au format pbm
(portable bitmap) ascii, semblable à celui des images en niveaux de gris de l’exercice 7 :

29 septembre 2011 v.473/473 24 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

– les deux premières lignes de ce fichier sont un en-tête que l’on ne modifiera pas : la première indique le
type de fichier (P1 pour pbm ascii), la seconde la géométrie de l’image (nombre de lignes et de colonnes) ;
– les lignes suivantes correspondent aux pixels noirs (1) ou blancs (0) de l’image parcourue de gauche à
droite puis de haut en bas ; chaque ligne comporte au plus 70 caractères.
Copier ce fichier depuis le compte de l’UE. Afficher l’image qu’il représente avec display ou xv par
exemple. On souhaite modifier ce fichier texte pour afficher le caractère & en blanc sur fond noir, via
différentes méthodes :
1. avec un éditeur de texte interactif ;
2. avec le filtre sed ;
3. avec le filtre tr et d’autres filtres élémentaires.

Solution
1. sous vi
3,$s/0/2/g
3,$s/1/0/g
3,$s/2/1/g
2. sed -e ’3,$s/0/2/g’ -e ’3,$s/1/0/g’ -e ’3,$s/2/1/g’ esperluette.pbm
autre solution : sed -e ’3,$y/01/10/’ esperluette.pbm
3. avec tr sur le corps de l’image seulement (découper et recoller)
tail -n +3 esperluette.pbm | tr 01 10 > corps
head -n 2 esperluette.pbm | cat - corps > tmp
mv tmp esperluette.pbm
Création de bitmaps à partir des polices cmr de tex
cd /usr/local/exports/latex/TEXLive6b/texmf/fonts/pk/ljfour/public/cm
pktopbm cmr10.3761pk -c38 -x 380 /tmp/jal/esperluette-.pbm
pour le -x, voir avec xv puis bouton milieu de la souris pour afficher le numéro du pixel
pnmtopnm -plain /tmp/jal/esperluette-.pbm > /tmp/jal/esperluette.pbm
pour passer en ascii 0/1

2011–2012 25 29 septembre 2011 v.473/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

Compléments du TE 3
Ex. 10 : Trace d’une matrice carrée (awk) A 15 min.
Le fichier mat5-5.dat stocke une matrice carrée 5 par 5. Sans faire d’hypothèse mat5-5.dat
11 12 13 14 15
sur la taille de la matrice, écrire les programmes awk qui calculent :
21 22 23 24 25
1. la somme des éléments de sa deuxième colonne ; 31 32 33 34 35
2. la somme des éléments de sa troisième ligne 41 42 43 44 45
51 52 53 54 55
3. AB sa trace (somme des éléments diagonaux).
Solution
1. {s+=$2} END{print s}
2. NR==3 {for (i=1;i<=NF;i++) {s+=$i} ; print s; exit} exit facultatif
3. {s+=$NR} END{print s}

Ex. 11 : Édition d’un fichier fortran 90 (sed, grep) B 15 min.


On considère le fichier fortran 90 trinome.f90. Pour répondre aux questions suivantes, utiliser les filtres
grep, sed ou un éditeur en repartant à chaque fois de la version originale de trinome.f90.

1 program trinome
2 !
3 ! résolution de l’équation du second degré
4 ! mise à jour le 13/10/2005
5 !
6 ! déclaration des variables
7 implicit none
8 real :: a, b, c
9 real :: x1, x2
10 real :: delta
11 real :: q
12 ! saisie des données
13 write(*,*) ’résolution de l’’équation du binôme ax^2+bx+c=0’
14 write (*,*) ’entrer les trois coefficients a, b, c’
15 read (*,*) a,b,c
16 write (*,*) ’a=’, a, ’ b=’, b, ’ c=’, c
17

18 ! il vaudrait mieux tester abs(a) > tiny(a)


19 if (a/=0.) then
20 write (*,*) ’ vrai degré deux’
21 ! cas d’un vrai second degré
22 delta=b*b-4.*a*c
23 if ( delta<0. ) then
24 ! pas de solution réelle
25 write (*,*) ’pas de solution réelle’
26 elseif ( delta==0. ) then
27 ! racine réelle double
28 write (*,*) ’racine double réelle’
29 x1=-b/(2.*a)
30 write (*,*) ’ x=’, x1
31 else
32 ! deux racines réelles
33 write (*,*) ’deux racines réelles ’
34 ! calcul classique à éviter pour des raisons de précision
35 ! x1=(-b+sqrt(delta))/(2.*a)

26 septembre 2011 v.461/473 26 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

36 ! x2=(-b-sqrt(delta))/(2.*a)
37 ! => sommer des termes de même signe
38 !
39 ! sign(u,v)=+|u| si v>0
40 ! -|u| si v<0
41 !
42 q=-(b+sign(sqrt(delta),b) ) / 2.
43 x1=q/a
44 x2=c/q
45 write (*,*) ’ x1=’, x1, ’ x2=’, x2
46 endif
47 else
48 ! degré un ou zéro
49 ! il vaudrait mieux tester abs(b) > tiny(b)
50 if (b/=0.) then
51 ! degré un
52 write (*,*) ’ degré un’
53 x1=-c/b
54 write (*,*) ’une solution unique’
55 write (*,*) ’ x=’, x1
56 else
57 ! degré zéro
58 write (*,*) ’ degré zéro’
59 ! il vaudrait mieux tester abs(c) > tiny(c)
60 if (c/=0.) then
61 write (*,*) ’pas de de solution’
62 else
63 write (*,*) ’infinité de solutions’
64 endif
65 endif
66 endif
67 stop
68 end program trinome
1. Faire une copie de sauvegarde du fichier trinome.f90.
2. Créer un fichier constitué des lignes 23 à 46 de trinome.f90.
Solution
head -n 46 trinome.f90 | tail -n 24
sed -n -e ’23,46p’ trinome.f90
3. Créer un fichier ne contenant que les lignes de commentaires de trinome.f90. On rappelle qu’en
fortran 90, une ligne est un commentaire si son premier caractère non-blanc est un point d’excla-
mation (!).
Solution
grep ’^ *!’ trinome.f90
sed -n -e ’/^ *!/p’ trinome.f90
4. Créer un fichier omettant tous les commentaires de trinome.f90
Solution
grep -v ’^ *!’ trinome.f90 ou
grep ’^ *[^ !]’ trinome.f90 différences liées aux lignes vides
sed -n -e ’/^ *[^ !]/p’ trinome.f90
5. Ajouter des blancs après les virgules.
Solution
sed -e ’s/,/, /g’ trinome.f90
:%s/,/, /g sous vi

2011–2012 27 26 septembre 2011 v.461/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

6. Insérer des blancs de part et d’autres des opérateurs arithmétiques "+-".


Solution
sed -e ’s/[+-]/ & /g’ trinome.f90
:%s/[+-]/ & /g sous vi
Éviter le = car cela casse les opérateurs /=, == par exemple, même problème avec * et **.
7. Passer toutes les ocurrences des mots clefs if, then, else, et endif en majuscules.
Solution
sed -e ’s/endif/ENDIF/’ \
-e ’s/if/IF/’ \
-e ’s/then/THEN/’ \
-e ’s/else/ELSE/’ \
trinome.f90
Attention endif avant if ( !) et elseif traité par else et if sans le demander explictement. Pas
de g car un seul par ligne. Idem sur la ligne ex sous vi

Ex. 12 : Mise en forme pour graphique (awk) B 20 min.


On souhaite représenter graphiquement l’évolution de l’endettement consigné dans le fichier depenses.
1. Calculer l’axe des temps en jours depuis le début de l’année 2000. Pour simplifier, on prendra des
mois de 30 jours et des années non bissextiles.
2. Ordonner les emprunts en fonction de ce numéro de jour.
3. Stocker dans un fichier de trois colonnes nommé dettes.dat, le numéro du jour, le montant de
l’emprunt et la dette cumulée.
4. Visualiser ce fichier grâce à la commande plot-dettes.sh. Le shell-script plot-dettes.sh appelle
le programme gnuplot qui permet de créer des graphiques à partir de la ligne de commande.
5. Repérer le processus associé à l’affichage graphique. Comment terminer l’affichage sans saisir q dans
la fenêtre gnuplot ?

Solution
awk -f abscisses-depenses.awk depenses | \
sort -k 9,9n | awk ’{s+=$7; print $9, $7,s}’ > dettes.dat
où abscisses-depenses.awk est le script-awk suivant
{
jour=$2 +30*$3 + 365*($4-2000)
print $0, jour
}
Sous awk, on pourrait compléter pour traiter les dates de façon plus réaliste (durée des mois, années
bissextiles).
Le script de visualisation utilise la redirection d’entrée pour gnuplot pour éviter de multiplier les fichiers
annexes :
#! /bin/sh
# représentation graphique de l’endettement

# structure Here Document pour gnuplot qui attend soit


# un fichier, soit des commandes en interactif
#
echo ’taper "q" dans la fenetre gnuplot pour terminer’

# attention: éviter l’interprétation des commandes gnuplot


# par le shell : EOF entre quotes

26 septembre 2011 v.461/473 28 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

gnuplot -persist <<’EOF’


# graphique d’endettement en fonction du temps
#
plot ’dettes.dat’ using ($1):($2) with impulses,\
’dettes.dat’ using ($1):($3) with lines

EOF
#

Ex. 13 : Notes AB 20 min.


Le fichier notes1.dat contient les notes d’un groupe d’étudiants. Le point-virgule ";" peut tenir lieu de
séparateur entre colonnes (comme dans les fichiers au format CSV exportés par les tableurs).
notes1.dat
Nom Prenom Initiales;cc1;cc2;ex;oral
Legrand Jean JL;10;12;13;14
Dupont Yves YD;9;7;9;12
Durand Claire CD;8;12;11;10
Lefort Corine CL;15;14;14;12

1. Utiliser la commande awk pour permuter les notes d’oral et d’examen (ex). Comment restituer le
séparateur « ; » ?
Solution
BEGIN{FS=";";OFS=";"}
{print $1,$2,$3,$5,$4}
Solution
BEGIN={";"; OFS=";"}
{tmp=$4; $4=$5; $5=tmp; print $0}
Solution
BEGIN={";"; OFS=";"}
{tmp=$4; $4=$5; $5=tmp; for (i=1; i<=NF; i++){print $i}}
2. Calculer la moyenne par épreuve sur l’ensemble du groupe d’étudiants et l’afficher.
Solution
BEGIN{FS=";"}
NR==1{ print $0; print "moyennes par épreuve"}
NR > 1 {
scc1+=$2
scc2+=$3
se+=$4
so+=$5
}
END{print "moyennes", scc1/(NR-1), scc2/(NR-1), se/(NR-1), so/(NR-1)}
Attention, sous awk les variables de langue pilotent la notation décimale : c’est LC_NUMERIC qui per-
met de passer du point décimal (si LC_NUMERIC=en_US par exemple) à la virgule (si LC_NUMERIC=fr_FR
par exemple). On peut le vérifier en positionnant ponctuellement la langue quand on lance la com-
mande, comme suit (sans données d’entrée) :
LC_NUMERIC=en_US awk --posix ’END{print 1/2}’ </dev/null donne 0.5
LC_NUMERIC=fr_FR awk --posix ’END{print 1/2}’ </dev/null donne 0,5

3. B Calculer la moyenne des notes pour chaque étudiant et l’afficher.


Solution

2011–2012 29 26 septembre 2011 v.461/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

# moyenne2-notes.awk
BEGIN{FS=";"}
NR==1 {print $0,"Moyenne"}
NR > 1 {
moy=0
for (i=2;i<=NF;i++) moy+=$i
moy=moy/(NF-1)
print $0,moy
}

4. Utiliser la commande awk pour permuter nom et prénom.

Solution
BEGIN{FS=" ";OFS=" "}
{print $2,$1,$3}

Solution
BEGIN={" "; OFS=" "}
{tmp=$1; $1=$2; $2=tmp; print $0}

Solution

BEGIN={" "; OFS=" "}


{
tmp=$1; $1=$2; $2=tmp;
for (i=1; i<=NF; i++)
{printf("%s ", $i)}
printf("\n")
}

5. B Reprendre la permutation nom–prénom avec la commande sed et conclure.

Solution
s/\(.*\) \(.*\) \(.*\)/\2 \1 \3/

Solution
s/\([^ ]*\) \([^ ]*\) \([^ ]*\)/\2 \1 \3/
est nettement préférable à cause de l’avidité due au multiplicateur *. Il essaie d’avaler tout ce qu’il
peut et donc, si le délimiteur n’est pas explicitement exclus de l’ensemble des caractères constituant
un champ, le premier multiplicateur va absorber tous les délimiteurs qui ne sont pas explicitement
spécifiés sur l’expression recherchée.
6. B Reprendre la permutation nom–prénom avec awk puis sed sur le fichier notes1+blancs.dat.
Expliquer.

Solution
Les premières solutions avec awk et sed sont en défaut !

Ex. 14 : Utilisation de l’éditeur vi AB


1. À partir du répertoire : ~lefrere/M1/2010-2011/etu/mni/unix/te3/, recopier dans le répertoire
de travail que vous vous êtes créé pour cette séance les fichiers :
ref-vi-vim.txt qui est le fichier à éditer
instructions-vi-vim.txt qui contient l’exercice à effectuer et qu’il est conseillé d’imprimer.
2. Ouvrir le fichier ref-vi-vim.txt sous vi et appliquer les actions décrites dans le fichier texte
instructions-vi-vim.txt (ce qui suit le caractère #, et le caractère # lui-même, ne doivent pas
être entrés au clavier). Commenter l’effet des requêtes proposées.

7 octobre 2010 v.304/473 30 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

1 # CONVENTIONS: <ESC> touche d’echappement


2 # <RET> retour chariot
3 # chaque ligne correspond a une action dont il faut observer
4 # l’effet avant de taper la ligne qui suit, mais NE PAS faire
5 # de retour chariot sauf s’il est explicitement demande par <RET>
6 # # : commentaires apres le diese
7 # NB: seuls les blancs au milieu des lignes sont significatifs
8 # les points de "reprise" (d’ou l’on peut repartir en cas de panique
9 # en sortant par ":q!" puis en re-editant le fichier initial)
10 # sont notes par <!>
11 #
12 # deplacements simples
13 1G # première ligne (vim mémorise la dernière position)
14 $ # fin de ligne
15 0 # debut de ligne
16 3| # colonne 3
17 6| # colonne 6
18 3G # ligne 3
19 5|
20 w # debut du mot suivant
21 w
22 w # attention aux signes de ponctuation
23 w
24 b # debut du mot precedent
25 b
26 b
27 e # fin du mot suivant
28 e
29 e
30 e
31 3w
32 2w
33 5e
34 +
35 $
36 16G
37 $
38 -
39 G # fin de fichier
40 1G
41 <CTRL F> # avance d’un ecran
42 <CTRL B> # retour d’un ecran
43 <CTRL F>
44 <CTRL F>
45 <CTRL F>
46 :1<RET> # debut de fichier <!>
47 # recherche de chaines de caracteres
48 /mot<RET> # vers l’avant (ne pas oublier de saisir Entrée)
49 n # meme direction
50 n
51 N # sens oppose
52 ?vers<RET> # vers l’arriere
53 n
54 n
55 N
56 /<RET> # vers l’avant (par défaut même recherche)

2011–2012 31 7 octobre 2010 v.304/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

57 ?<RET> # vers l’arriere


58 # insertions simples
59 :1<RET> <!>
60 2w
61 il’editeur <ESC> # avant le curseur
62 u # "undo" (attention, différences vi/vim si on répète)
63 A (et à vim)<ESC> # en fin de ligne
64 u
65 5|
66 ITE3: <ESC> # en debut de ligne
67 r- # remplace un caractere
68 e
69 a rapide<ESC> # apres le curseur
70 o # ligne apres
71 +++<ESC>
72 O # ligne avant
73 :::<ESC>
74 J # jointure avec la ligne suivante
75 r<RET>
76 -
77 J
78 A=<ESC>
79 . # repetition de la commande
80 .
81 10.
82 # suppressions et deplacements de texte <!>
83 :1<RET>
84 /-<RET>
85 x # suppression du caractere courant
86 p # recopie memoire tampon apres
87 x
88 P # recopie memoire tampon avant
89 X # suppression du caractere a gauche
90 p
91 3w
92 dw # suppression du mot
93 P
94 /Requêtes<RET>
95 cwCommandes<ESC> # modification d’un mot
96 dd # suppression de la ligne
97 p
98 dd
99 P
100 -
101 ddp # echange de deux lignes
102 /(écha<RET>
103 % # delimiteur fermant
104 % # delimiteur ouvrant
105 D # suppression de la fin de la ligne
106 p
107 /==<RET>
108 yy # memorisation d’une ligne
109 p
110 2yy # memorisation de deux lignes
111 /1)<RET>
112 P

7 octobre 2010 v.304/473 32 2011–2012


UPMC M1 : MNI Correction du TE 3. Redirections, tubes et filtres

113 G
114 p
115 :1<RET> # <!>
116 Rintroduction <ESC> # mode remplacement
117 w
118 D
119 :q! # sortie forcee sans enregistrer les modifications
1 Initiation rapide à vi
2

3 1) Mise en garde: requêtes et saisie de texte


4 - au lancement, contrairement à d’autres éditeurs qui
5 recopient dans le fichier les caractères frappés,
6 l’éditeur vi attend des requêtes d’édition
7 (déplacements, suppressions, copies, ou ... requêtes de saisie):
8 les touches frappées sont donc interpretées
9 - pour saisir du texte, il faut d’abord lancer une requête particulière
10 telle que i, I, a, A, o, O, c ...
11 et la saisie se termine en frappant la touche: ESCape (échappement)
12 l’éditeur est alors prêt a interpréter d’autres requêtes
13

14 2) Manipulation des fichiers


15 Requêtes ex
16 :w (write = sauvegarde dans le fichier ouvert à l’entrée dans vi)
17 :w fic (write = sauvegarde dans le fichier fic)
18 :q (quit = sort de l’editeur, suppose les modifications sauvegardées)
19 :q! (sortie forcée sans sauvegarde)
20 Requête spécifique vi
21 ZZ (sortie avec sauvegarde)
22

23 3) Déplacements élémentaires du curseur


24 3.1) Déplacements relatifs en termes de caractères
25 k : vers le haut
26 j : vers le bas
27 l : vers la droite
28 h : vers la gauche
29 On peut aussi, si la configuration est correcte, utiliser les flèches.
30 (voir fichier .exrc)
31

32 3.2) Déplacements en termes de mots


33 w : début du mot suivant (w=word)
34 e : fin du mot suivant (e=end)
35 b : début du mot précédent (b=begining)
36

37 3.3) Changement de colonne


38 0, $ : début, fin de la ligne courante
39 n| : colonne n
40

41 3.4) Changement de ligne


42 - : premier caractère de la ligne précédente
43 + : premier caractère de la ligne suivante
44 nG : ligne numero n (:n avec ex)
45 G : dernière ligne (:$ avec ex)
46

47 3.5) Changement d’écran


48 ^F : écran suivant (F=forward)
49 ^B : écran précédent (B=backward)

2011–2012 33 7 octobre 2010 v.304/473


Correction du TE 3. Redirections, tubes et filtres UPMC M1 : MNI

50 On peut aussi, si la configuration est correcte, utiliser les touches


51 Next et Previous Page
52 (voir fichier .exrc)
53

54 4) Insertion
55 i, a : insère avant, après le curseur (i=insert, a=append)
56 I, A : insère en début, en fin de ligne
57 o, O : ouvre une ligne après, avant la ligne courante (o=open)
58

59 5) Modification
60 r : remplace un caractère sans passage en mode insertion (r=replace)
61 ~ : changement minuscule <-> majuscule sans passage en mode insertion
62

63 cw : modifie un mot (c=change, w=word) passage en mode saisie (Echap à la fin)


64

65 6) Mémorisation
66 yw : mémorise le mot courant (y=yank)
67 yy, Y : mémorise la ligne courante
68

69 7) Destruction - déplacement de texte


70 x : détruit le caractère courant
71 dw : détruit le mot courant (d=delete)
72 dd : détruit la ligne courante
73

74 p, P : place le texte détruit ou mémorisé après, avant le curseur (p=paste)


75

76 8) Recherches
77 /motif : recherche le motif vers l’avant
78 ?motif : recherche le motif vers l’arrière
79 n, N : nouvelle recherche dans le même sens, en sens opposé (n=next)
80

81 9) Divers
82 . : répète la dernière commande d’édition
83 u : annule la dernière modification (u=undo)
84 Comportement différent entre vi et vim en cas de répétition
85 Attention: sous aix (ibm) u ramène le curseur sur le 1er caractère non blanc
86 U : restitue la ligne courante (annulant toutes les modifications
87 faites tant que le curseur n’a pas quitté la ligne)
88 % : si le curseur pointe sur un délimiteur ouvrant ([{, positionne
89 sur le délimiteur fermant associé )]} ou réciproquement
90 ===================================================================
91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

7 octobre 2010 v.304/473 34 2011–2012

Vous aimerez peut-être aussi