Vous êtes sur la page 1sur 26

Les Outils de Recherche et d’Edition

Il existe une grande famille de programmes qui lisent une entrée, réalisent une transformation et
écrivent un résultat. C’est ce qu’on appelle des filtres.
Ce chapitre présente les filtres les plus utilisées. Nous commençons par ceux qui effectuent des
recherches dans les fichiers (la famille grep) ou des recherches de fichiers (find). Le reste du chapitre sera
réservé à l'étude de deux outils de "transformation de texte" programmables et universels. Ils sont
programmables, en ce sens que les transformations à réaliser sont définies dans un langage de programmation
simple. Ces programmes sont sed et awk qui sont des généralisations de grep.

1. Recherche d'une chaîne dans un fichier - la famille GREP -

Unix offre trois commandes de même famille, grep, egrep et fgrep, pour afficher les lignes de fichiers
donnés en paramètre et qui contient un motif donné. Leurs syntaxes est le même :

grep [ option ] <motif> [<fichier> ...]

Le motif est une expression régulière dans laquelle certains caractères ont une signification particulière.

grep est très utile pour trouver les occurrences d'une variable dans un programme, ou des mots dans un
document, ou pour sélectionner des parties des sorties d'un programme.
Sauf option contraire, chaque ligne ayant cette propriété est écrite sur la sortie standard. Il est
recommandé d'entourer d'apostrophes les expressions contenant des caractères spéciaux du langage de
commandes utilisé.

Options
-v seules les lignes ne contenant pas le motif sont affichées;
-c seul le nombre de lignes satisfaisantes est affiché
-i ignore la distinction minuscule/majuscule dans les comparaisons (grep
seulement)
-l seules les noms de fichiers contenant le motif sont affichés;
-n numérote les lignes affichées;
-e motif lorsque le motif commence par un tiret;
-f fichier le motif est dans le fichier (egrep et fgrep)
Le code de retour est 0 si un motif a été trouvé, 1 sinon,
et 2 s'il y' a eu des erreurs.

Exemples
$ grep -n variable *.ch cherche variable dans les sources
$ grep From $MAIL affiche les en-têtes des messages
$ grep From $MAIL¦ grep - v marie autre que marie
$ grep -c marie $HOME/lib/annuaire trouve le numéro de marie dans l'annuaire
$ who¦ grep marie est-elle connectée?
$ ls¦ grep -v temp les noms de fichiers ne contenant temp

expressions régulières de grep et fgrep (par ordre décroissant de précédence)


c tout caractère non spécial
\c ignore la signification spéciale de c
^ début de ligne
$ fin de ligne
. n'importe quel caractère unique
[...] n'importe quel caractère unique ...; des suites comme a-z sont possibles
[^...] n'importe quel caractère unique figurant pas parmi ...
\n ce qui a été identifié par la nième sous expression \(...\) (grep seulement)
r* zéro ou plus occurrences de r

ENSI/OMS/Intro OS/II1/ page 1


r+ une ou plus occurrences de r
r? zéro ou une occurrence de r
r1¦r2 r1 suivi de r2
\ (r \) sous expression r repérée (grep seulement); peut être imbriqué
(r) expression régulière r2 (egrep seulement), peut être imbriqué

Exemples
$ grep '^From'$MAIL imprime toutes les lignes commençant par From
$ ls-1¦ grep '^d' imprime seulement les lignes décrivant un répertoire
$ ls -1 ¦ grep'^.......rw' imprime les fichiers qui peuvent être lus ou écrits par tous
$ grep '^[^:]*::' /etc/passwd trouver les utilisateurs qui n'ont pas de mots de passe

grep est le plus ancien membre d'une famille de programmes qui contient également egrep et fgrep.
Leur comportement est à peu près le même. fgrep recherche plusieurs expressions simultanément et egrep traite
de vraies expressions régulières - les mêmes que grep, mais avec un opérateur 'ou' et des parenthèses pour
grouper les expressions.

2. Recherche d'un fichier : find

find descend récursivement des sous-hiérarchies de répertoires données par leur racine, en cherchant à
appliquer à des fichiers précisés par un ou plusieurs critères se sélection (nom, type, date) une commande
donnée.

find [répertoire] + [expression] +

répertoire est la liste des racines des sous-hiérarchies à parcourir. expression est une suite de primitives
exprimant à la fois les critères de sélection à des fichiers et les actions à leur appliquer. Lorsque le critère est
vrai, l'action est exécutée. Ces primitives sont :
-name <motif> vrai si le motif s'applique sur le nom du fichier courant;
-user <nom> vrai si le fichier courant appartient à l'utilisateur nom;
-atime <n> vrai si le fichier a été utilisé dans les n derniers jours; peu utilisable;
-mtime <n> vrai si le fichier a été modifié dans les n derniers jours;
-newer <fichier> vrai si le fichier courant a été modifié plus récemment que fichier;
-type <x> vrai si le type du fichier est x avec :
b pour fichier spécial bloc,
c pour fichier spécial caractère,
d pour fichier répertoire
f pour fichier ordinaire,
p pour tube nommé (System III/V);
-perm <octal> vrai si les permissions du fichier correspondent au nombre octal donné;
-links <n> vrai si le fichier a n liens;
-group <nom> vrai si le groupe propriétaire du fichier est nom;
-size <n> vrai si le fichier contient <n> blocs;
- exec commande vrai si la commande restitue une valeur de sortie nulle;
la fin de la commande doit être ponctuée par \;
et le nom du fichier examiné est représenté par {};
-print le nom de fichier doit être imprimé;
- inum <n> vrai si le i-noeud du fichier à pour numéro n;
-\(expression\) a pour valeur booléenne celle de l'expression parenthésée.

Remarque
Toutes ces primitives peuvent être composées avec les opérateurs booléens : de négation !, de
conjonction (concaténation des expressions), de disjonction -o, et les parenthèses \(\).

Exemple
find . \( -name *.c -o -name *.f \) -mtime -30 exec ls -1 {} \;
on applique la commande ls -1 à tous les fichiers qui sont des sources C ou FORTRAN modifiés
depuis moins d'un mois, et qui appartiennent à la hiérarchie dont la racine est le répertoire courant (.):

ENSI/OMS/Intro OS/II1/ page 2


find $HOME -newer datesauv -print
affiche les fichiers de l'arborescence définie par le répertoire personnel de l'usage modifiés après le
fichier datesauv

3. Tri et fusion

3.1- Tri
sort [options] [clé [option]] + [<fichier> ] +

trie les lignes et écrit les résultats sur la sortie standard sauf si l'option -est utilisée. Le tri sur les lignes
est lexicographique sur l'ensemble des fichiers.

options
-c (check) vérifie que le fichier est trié; la sortie n'existe que si le fichier n'est pas trié;
-u (unique) ne garde qu'une ligne parmi toutes celles qui ont la même clé;
-o <fichier> (output) envoie la sortie sur <fichier>
-d (dictionary) les comparaisons ne se font qu'avec les lettres, les chiffres et les blancs;
-f lettre minuscules et majuscules sont confondues;
-n clé numérique (signée éventuellement);
-i les caractères dont le code ASCII est extérieur à l'intervalle octal 040-0176 sont ignorés;
-r renverser l'ordre du tri;
-b ignorer les blancs en début de champ;
-t<x> le délimiteur de champ dans les lignes est le caractère <x> et non le TAB
clé limite le champ des comparaisons aux portions de lignes, elle est de la forme + debut -fin
debut est le premier champ servant à faire la clé (numérotation à partir de zéro),
fin est le numéro du premier champ qui n'appartient pas à la clé.

Exemples
sort + 1 -2 f
trie f sur une clé formaté par le deuxième champ de chaque ligne
Une clé peut être préciser des portions de champs. Dans ce cas, debut et fin sont de la forme m.n
(éventuellement l'une des options b d f i ou r) où m donne le nombre de champs à sauter depuis le
début de ligne et n le nombre de caractères à sauter en début de champ avant de commencer la
comparaison.
$ sort + 2.3 -5.0 f
trie f sur une clé qui commence au troisième champ, et qui se termine à la fin du cinquième champ.
$ ls ¦ sort
trie les noms de fichiers en ordre alphabétique
$ ls -s ¦ sort -nr
trie par ordre de taille décroissante
$ ls -1 ¦ sort + 3 nr
trie par taille décroissant; après avoir sauter les 3 premiers champs
$ who ¦ sort + 4n
trie les plus anciennes connexions
$ sort -t, + 4bf -5bf -0f - 1f. ft>diplome.t
Soit f.t un fichier d'étudiants qui la format suivant :
nom, prénom, jj/mm/aa, code Diplôme
tri sur diplôme, puis alphabétiquement, sortie sur diplome.t
$ sort -t, +2.7b -2.9b + 2.4b - 2.6b + 2b. - 2.2b f.t >age.t
Soit f.t un fichier d'étudiants qui la format suivant :
nom, prénom, jj/mm/aa, code Diplôme
tri par âge, la date étant la date de naissance, sortie sur age.t.
Damargi, Mariam, 01/03/70, cISET
champs 0 1 2 3
+ 2.7 signifie que la clé commence sur le 7ème caractère du champ 3 (soit le premier a de ...
jj/mm/aa, le chiffre 7), et -2.9 signifie qu'elle s'arrête au 9 ème caractère après la fin du deuxième
champ (0 de 70, sur l'exemple). Le b collé pour ignorer les éventuels blans entre la virgule et la date.

ENSI/OMS/Intro OS/II1/ page 3


3.2 Fusion
sort -m [options] [clé [option]] + [<fichier1> ] +

Les fichiers doivent préalable être triés sur les clés de fusion.

4. L'éditeur de flot sed

sed est un éditeur non interactif qui permet le traitement de fichiers texte. Il utilise surtout dans les sous-
programmes scell, et comme filtre dans les listes de commandes.

sed [ -n] [<requête>] [ -e <requête>] * [ -f <script> ]] [<fichier>] *

sed recopie le ou les fichiers <fichier> (par défaut l'entrée standard) sur la sortie standard, en appliquant
à chaque ligne les requêtes qui suivent l'option -e (un par requête), ou les requêtes qui se trouve dans le fichier
<script>, ou la requête s'il y en a une.

4.1. Forme générale des requêtes de sed


Une requête sed est de la forme :

[adresse1 [adresse2]] commande arguments]

L'option -n demande à sed de n'afficher sur la sortie que les lignes sur lesquelles on applique la
commande p.
adresse est le numéro absolu d'un ligne de texte ( dans le cas où il ya plusieurs fichiers sources, sed
considère qu'il y a en un formé de la concaténation des différents fichiers), ou le $ pour dernière ligne, ou une
expression régulière palace entre deux barres (/.../) et définissant un motif figurant dans la ligne adressé.

4.2 Mode de fonctionnement


sed ne travaille pas sur une image du fichier en mémoire : tampon ne contient qu'une ou quelques lignes
du fichier à un instant donné. Toutes les requêtes que l'on fournit à sed sont appliquées à chacune des lignes
défilant dans le tampon, en fonction de l'adressage de ces lignes dans les reduêtes. Un tampon auxiliaire permet
les déplacements de blocs de texte dans le fichier.

4.3 Les commandes de manipulation de l'espace de travail


commande est une lettre suivi d'arguments. Toutes les requêtes peuvent avoir zéro, une ou plusieurs
adresses sauf a et i (zéro ou une).
a\ <texte> ajoute des lignes à la sortie jusqu'à la première ligne ne se terminant pas par \
b <etiq> saut à la commande : <etiq>
c\ remplace des lignes comme pour a
d détruit la ligne courante; lit la suivante
i\ insère le texte avant la prochaine sortie
l imprime la ligne
q termine
r fichier lit fichier et copie son contenu en sortie
s/<anc>/<nouv>/ f : substitue l'expression régulière <anc> par la chaîne de substitution nouv. f est un
indicateur :
g : remplace toutes occurences traitées;
p : le contenu du tampon est écrit si une substitution est effectuée
w <fichier> écrit dans <fichier> si une substitution est effectuée
t <etiq> branchement à : <etiq> si la dernière substitution a réussi
w <fichier> écrit dans <fichier>
y/<ch1>/<ch2>/ toutes les occurences du tampon des caractères figurant dans la chaîne 1
sont remplacés par le caractère correspondant de la chaîne 2.
= imprime le numéro de la ligne
! commande-sed la commande est effectuée sur les lignes non sélectionnées
{ et } associe à un espace d'adressage une liste de commandes
N la ligne courante est ajoutée au tampon qui en contient alors deux

ENSI/OMS/Intro OS/II1/ page 4


D détruit le début du tampon jusqu'à la première fin de ligne include
P affiche le début du tampon jusqu'à la première fin de ligne incluse
h le tampon est copié dans le tampon auxilière dont le contenu est détruit
H le tampon est ajouté dans le tampon auxilière; le séparateur est la fin de ligne
g le tampon auxilière est copié dans le tampon dont le contenu est détruit
G le tampon auxilière est ajouté dans le tampon ;; le séparateur est la fin de ligne
x échange entre les contenus du tampon et du tampon auxilière.

Exemples
$sed 's/UNIX/UNIX (TM)/g' f1 f2
remplace la chaîne UNIX par UNIX (TM) dans f1 f2
$sed '10,/{#.*}/s/ *//g' f>>f
remplace les espaces qui se suivent par un seul blanc de la dixième ligne jusqu'à la première
ligne (après la dixième) qui contient une chine de la forme {#...#}
$ who\sed's/. * //
remplace un espace suivi d'un nombre quelconque de caractères jusqu'au dernier espace la
ligne par un seul espace
$ sed '/fin/ q'
imprime son entrée sur la sortie jusqu'à la première ligne contenant le mot fin
$ sed'/^***/d'
détruit les lignes commençant par ***
$ sed 's/$^n'
ajoute une fin de ligne à la fin de chaque ligne
$ sed '1,/^$/d
détruit jusqu'à la première ligne vide
$ sed -n'/^$/,/^fin/p
imprime chaque groupe lignes depuis une ligne vide jusqu'à une ligne débutant par fin
$ sed -n '/exp/w fichier 1> /exp/!w fichier2
écrit les lignes vérifiant exp sur fichier1, sinon sur fichier2

# exemple : Remplace une fin de ligne par le séparateur :, sauf s'il est suivi par !.
# debut de la boucle
: debut
# ajout de la suivante dans le tampon
N
# remplacer la fin de ligne par s'il n'ya pas de!
s/ \n \([^!]\) / : 1 /
# si la substitution a réussi, recommencer
t debut
# sinon, afficher la ligne d'adresse complète
P
# et détruire le ! qui reste dans le tampon
d

5. Le transformateur de texte AWK

awk est un outil non interactif pour traiter des textes, les transformer, les éditer, faire des calculs
élémentaires sur le contenu. Le nom de awk vient de ses trois concepteurs : Alfred V. Aho, Peter J. Weinberger
et Brian W. Kernighan. (ebook en ligne : http://en.wikibooks.org/wiki/AWK)

awk manipule les fichiers ligne par ligne et adresse les champs à l'intérieur des lignes. Pour traiter les
champs, le programmateur dispose de variables et des instructions classiques des langages de programmation.

Quelques-unes des limitations de sed sont levées par awk. L'idée de base d'awk est la même que celle
de sed, mais les détails dérivent plutôt du langage C que d'un éditeur de texte.

awk [ -F <car>] { [ -f <fprog> ¦ <prog>]} [param] [ <fichier>]*

traite les fichiers référencés ligne par ligne, et chaque ligne est soumise à un programme awk (<fprog>,

ENSI/OMS/Intro OS/II1/ page 5


<prog>; si la ligne courante satisfaisant à une ou plusieurs sélections proposées dans le programme les actions
correspondants sont exécutées.

 Une ligne d'un programme awk a le format suivant :


sélection {actions}
 Les sélections sont des expressions les mêmes que dans egrep, ou peuvent être encore plus compliquées.
awk fournit deux expressions particulières, BEGIN et END. Les actions associées à BEGIN sont réalisées
avant que la première ligne soit lue; ce sont couramment des actions d'initialisation de variables. Les actions
associées à END sont réalisées après que la dernière ligne soit lue; ce sont couramment des actions
d’affichage de résultats finaux.

$ awk '/<expression régulière> / {print}' <fichier>...


fait la même chose que egrep

$ awk' {print}' <fichier>…


fait la même chose que cat

 L'option -F permet de définir le nouveau séparateur de champs, si ce n'est pas <espace> ou le caractère
<tab>. Les fichiers sont traités dont l'ordre où ils sont donnés en paramètres dans les lignes. Dans le cas où
aucun fichier n'est signalé, c'est l'entrée standard qui le sera.

 Les fichiers sont traités dont l'ordre où ils sont données en paramètres dans les lignes. Dans le cas où aucun
fichier n'est donné, c'est l'entrée standard qui le sera.

5.1. Traitement des champs


awk découpe le fichier qui lui soumis en enregistrements logiques (par défaut les lignes) eux-mêmes
découpés en champs. Un enregistrement (resp. un champs) est une suite de caractères délimitée par un délimiteur
d'enregistrement qui par défaut est le caractère <newligne> (resp. un délimiteur de champ qui par défaut le
caractère <esspace>).

De façon générale $1, $2, ...,$NF désignent le premier champ, le second champ, ... de l'enregistrement
courant noté $0 et NF est une variable dont la valeur est le nombre de champs de la ligne courante.

$ who
rim tty2 Sep 29 11 : 53
slim tty4 Sep 29 12 : 15

$ who ¦ awk ' {print $1, $5} ‘ imprime les noms et heurs de connexions
rim 11 : 53
slim 12 : 15

5.2. Les variables

- les variables utilisateurs


Les identificateurs sont définis comme dans le langage C. La déclaration et le type sont implicites. On
distingue les variables numériques (nombres flottants) et les variables chaînes. Les variables sont toutes
initialisées à la chaîne vide ", cette chaîne ayant comme valeur 0 dans les expressions arithmétiques. La
conversion de type est automatique au cours de opérations. Il est enfin possible d'utiliser les tableaux,
l'indexation étant réalisée avec les crochets comme en c.

- les variables prédéfinies


awk maintient des informations intéressantes en dehors du nombre de champs dans différentes variables
:
FILENAME nom du fichier courant d'entrée
FS séparateur de champs dans l'enregistrement courant
NF nombre de champs dans l'enregistrement courant
NR numéro de l'enregistrement courant
OFMT format de sortie des nombres (défaut %g, voir printf ...)
OFS séparateur de champs de sortie ( par défaut, un espace)
ORS séparateur de lignes en sortie ( par défaut fin de ligne)

ENSI/OMS/Intro OS/II1/ page 6


RS séparateur de lignes en entrée ( par défaut de ligne)

$ awk' {print NR, $0} ' monfichier


affiche le contenu de mon fichier avec le n° de ligne
$ awk ' {printf "%4d %sn\n", NR, $0} ‘ monfichier
même chose que précédemment mais le n° de ligne sur 4 caractères

5.3. Les sélections


Une sélection a l'une des formes suivantes :

- combinaison quelconque au moyen des opérateurs : ! ¦¦ && (et)


cf les définition pour l'utilitaire grep.

- expression régulière de la forme


< expression>~<expression régulière>
<expression>!~<expression régulière>

<expression><opérateur><expression>
avec <opérateur> est <<=><= ==!=

$2 =="" 2ème champ vide


$2 ~/$/ 2 ème champ identique à la chaîne vide
$2!~ /./ 2 ème champ ne contient aucun caractère
length ($2) == 0 2 ème champ de longueur nulle

$ awk -F: $2 == "" /etc/ passwd


affiche les utilisateurs qui n'ont pas de mot de passe
$ awk' BEGIN { FS =":"} $2 == ""' /etc/passwd
affiche les utilisateurs qui n'ont pas de mot de passe

- intervalle de la forme /motif/, /motif/


Les actions spécifiées sont exécutées pour toutes les lignes comprises entre la première ligne contenant le
premier motif et la ligne suivante contenant le second motif.

5.4. Les actions

Les opérateurs ( par ordre de priorité croissante)


=+= -=*=/= % = opérateurs d'affectation
¦¦ opérateur booléens OU;
<<exp1>> ¦¦ <<exp2>> est vraie si l'une des deux l'est.
<<exp2>> n'est pas évaluée si <<exp1>> ¦¦ est vraie
&& opérateur booléens ET; <<exp1>> est vraie si les deux le sont
! négation
>>=< <= ==!=~!~ opérateurs relationnels ~ et !~ sont des opérateurs de correspondance.
<espace> opérateur de concaténation de chaînes
+- plus, moins
*/% multiplication, division, reste
++ -- incrémentation, décrémentation (préfixé ou postfixé)

Les fonctions
cos (expr) cosinus de expr
exp (expr) exponentielle de expr
getline() lit la ligne suivante; retourne 0 si la fin de fichier, 1 sinon
index (s1, s2) position de la chaîne s1 dans la chaîne s2
int (expr) partie entière de expr
length (s) longueur de la chaîne s. Sans argument, $0 est pris comme argument.
log (expr) logarithme naturel de expr
sin (expr) sinus de expr

ENSI/OMS/Intro OS/II1/ page 7


split (s, a, c) découpe s en a [1], a[2], ..., a [n] suivant le délimiteur c ( par défaut la valeur de FS)
sprintf(fmt,...) formate ... en accord avec la spécification fmt
substr(s, m, n) sous-chaîne de s; début au caractère m, longueur maximale n

Les instructions
Elles apparaissent dans les actions et se terminent soit pat un; soit par un caractère de fin de ligne, soit par } ou
encore par # (début d'un commentaire qui se termine à la fin de ligne).

- Instruction de lecture
$0, $1 ... ,
Lit et parse une nouvelle ligne depuis le fichier
getline NR, FNR,
courant dans les variables standard $0, $1, etc.
NF
Lit une nouvelle ligne depuis le fichier courant
getline var juste var
vers la variable var. La ligne n'est pas parsée.
Lit et parse une nouvelle ligne depuis le
getline < "fichier" fichier "fichier" dans les variables standard $0, $1, $0, $1 ..., NF
etc.
Lit une nouvelle ligne depuis le
getline var < "fichier fichier "fichier" vers la variable var. La ligne n'est juste var
pas parsée.
Lit une nouvelle ligne dans le tube i.e. depuis la
"commande" | getline sortie standard de commande et vers les variables $0, $1 ..., NF
standard $0, $1, etc.
Lit une nouvelle ligne dans le tube i.e. depuis la
"commande" | getline var sortie standard de commande et vers la juste var
variablevar.

- Instructions d'affichage
print [<expression>, <expression> ...]
imprime les valeurs des expressions séparés par le caractère valeur de la variable OFS. Sans
argument, il y a impression de l'enregistrement complet ($0).L'impression se termine par une fin
de ligne.

printf (<format>, [<expression>, <expression> ...] )


idem qu’en C, imprime les expressions dans le format demandé.

Ces impressions peuvent être redirigées en les faisant suivre de > fichier ou >>fichier.

- Instruction conditionnelle
if (<expression>)
<instruction>
else
<instruction>
- Instructions répétitives
while (<expression>)
<instruction>

for (< var; <expr>; <expr>)


<instruction>

for (<var> in <tableau>)


<instruction>

- les autres instructions


break sortie de la boucle courant
continue poursuivre à l'itération suivante de la boucle
exit sortie du programme en cas d'exécution de la section END
et sinon passage à cette section

ENSI/OMS/Intro OS/II1/ page 8


next abandon de l'enregistrement courant et passage au suivant
Les fonctions
 déclaration :
function identificateur (param 1, param 2, ... ,param n) {
<Instructions constituant la fonction>
}
 appel :
identificateur( (param 1, param 2, ... ,param n)
 Exemple :
function Bonjour(Ajout) {
print"Bonjour " Ajout
}
# Appel de la fonction
BEGIN {
Bonjour("tout le monde")
}

5.5. Exemples

 utilisation des tableaux


$ envers : imprime son entrée à l'envers

awk' {ligne [NR]=$0}


END {for (i=NR; i>0; i--) ligne [i]}
' $*

 utilisation des tableaux associatifs


$ cat freqmot

#freqmot : compter les apparitions de mots dans un texte


awk '
{for (i=1; i< =NF; i++) num [$i]++}
END {for (mot in num) print mot, num [mot]}
' $*

 un exemple plus complexe


$ cat double

# recherche les mots doubles adjacents dans plusieurs fichiers


awk ‘
FILENAME ! = prevfile {
#nouveau fichier
NR=1
prevfile=FILENAME
}

NF<0 {
it ($i == $(i-1))
printf " double %s, fichier %s, ligne %s \n", $i, FILENAME, NR
if (NF >0) dernmot=SNF
}
' $*

ENSI/OMS/Intro OS/II1/ page 9


Listes d’exercices corrigés - Outils de Recherche et d’Edition

Ecrire un script shell permettant de faciliter l’utilisation de la commande find. L’objectif est de présenter
un menu à l’utilisateur pour choisir quel type de recherche il voudra réaliser à partir d’un répertoire
donnée. Exemple : affichage de la liste des fichiers ordinaires, affichage de la liste des fichiers appartenant
à un utilisateur donné, etc.

#script find1 qui affiche une liste de fichiers


# selon les besoins de l'utilisateur exprimés
# par un choix dans un menu

menu()
{
echo -e "\t\t 0) quitter"
echo -e "\t\t 1) sous répertoires de $dir"
echo -e "\t\t 2) liste des fichiers ordinaires de $dir"
echo -e "\t\t 3) liste des fichiers spéciaux de $dir"
echo -e "\t\t 4) fichiers de $dir ayant une taille donnée"
echo -e "\t\t 5) fichiers appartenant à un utilisateur donné"
echo -e "\t\t 6) fichiers récemment mis à jour"
echo -e "\t\t 7) fichiers récemment accédés"
echo -e "\t\t 8) fichiers récemment créés"
echo -e "\t\t 9) fichiers ayant des droits d'accès particuliers"
}

while true
do
echo -e "\n======================================================="

trap 'clear; exit' 2 3


echo -e "Répertoire à traiter : \c"; read dir
if test "$dir" = "."; then dir=`pwd`
elif test -d $dir ; then :
else echo -e ">>>>>>>>>>>REPERTOIRE INCONNU <<<<<<<<<\n"; exit 1
fi

menu
echo -e "\n\t\tChoisir parmi : \c"; read choix
case $choix in
0) exit;;
1) find $dir -type d -print;;
2) find $dir \( -type f -o -type l \) -print;;
3) find $dir \( -type c -o -type b -o type p -o -type s\) -print;;
4) echo -e "\ttaille min en octets : \c"; read min
min=`expr $min / 512`
echo -e "\ttaille max en octets : \c"; read max
max=`expr $max / 512` ; max=`expr $max + 1`
find $dir \( -size +$min -a -size -$max \) -print
;;
5) echo -e "\tnom de l'utilisateur : \c"; read nom
find $dir -user $nom -print
;;
6) echo -e "\tnombre de jours : \c"; read nbjour
find $dir -mtime -$nbjour -print
;;
7) echo -e "\tnombre de jours : \c"; read nbjour
find $dir -atime -$nbjour -print

ENSI/OMS/Intro OS/II1/ page 10


;;
8) echo -e "\tnombre de jours : \c"; read nbjour
find $dtime -$nbjour -print
;;
9) echo -e "\tpermission d'accès : \c"; read droit
find $dir -perm -$droit -print
;;
*) echo -e "\n>>>>>>>>>>> ERREUR dans la saisie ! <<<<<<<<<<<<\n"
;;
esac
done

[root@localhost grepfind]# find1

=======================================================
Répertoire à traiter : mmm
>>>>>>>>>>>REPERTOIRE INCONNU <<<<<<<<<

[root@localhost grepfind]# find1

=======================================================
Répertoire à traiter : .
0) quitter
1) sous répertoires de /home/omsaid/grepfind
2) liste des fichiers ordinaires de /home/omsaid/grepfind
3) liste des fichiers spéciaux de /home/omsaid/grepfind
4) fichiers de /home/omsaid/grepfind ayant une taille donnée
5) fichiers appartenant à un utilisateur donné
6) fichiers récemment mis à jour
7) fichiers récemment accédés
8) fichiers récemment créés
9) fichiers ayant des droits d'accès particuliers
Choisir parmi : 9
permission d'accès : 700
/home/omsaid/grepfind
/home/omsaid/grepfind/find1

=======================================================
Répertoire à traiter : /tmp

Choisir parmi : 2
/tmp/.X0-lock
/tmp/Xconfig
/tmp/kfm-cache-0/index.html
/tmp/kfm-cache-0/index.txt

=======================================================
Répertoire à traiter : .

Choisir parmi : 1
/home/omsaid/grepfind
/home/omsaid/grepfind/ss1rep
/home/omsaid/grepfind/ss2rep

=======================================================
Répertoire à traiter : ss1rep

Choisir parmi : 2
ss1rep/exple1

ENSI/OMS/Intro OS/II1/ page 11


ss1rep/exple2

=======================================================

Ecrire un script shell qui va traquer la liste des fichiers de taille nulle et ceux dont le bit SUID est mis en
place. Le script attend un paramètre en entrée qui doit correspondre à la spécification du chemin d’un
répertoire à partir duquel la recherche va être opérée. Si ce paramètre est absent, il s’agit du répertoire
courant.

#script find2 traquant les fichiers de taille nulle


# et de SUID-Bit mis en place

if test $# -gt 1
then echo erreur : trop de paramètres
echo usage : $0 [path]
exit 1
fi

echo ${1:-`pwd`} 1>/dev/null 2>/dev/null


echo $1
echo "liste des fichiers de taille nulle"
echo "=================================="
nbre=`find $1 -size 0 |wc -l`
find $1 -size 0
echo -e "\n>>>>>>>> TOTAL = $nbre \n"

echo "liste des fichiers avec SUID-Bit=1"


echo "=================================="
nbre=`find $1 -perm +4100 | wc -l`
find $1 -perm +4100
echo -e "\n>>>>>>>>> TOTAL = $nbre \n"

[root@localhost grepfind]# find2 /usr/man/fr


/usr/man/fr
liste des fichiers de taille nulle
==================================

>>>>>>>> TOTAL = 0

liste des fichiers avec SUID-Bit=1


==================================
/usr/man/fr
/usr/man/fr/man1
/usr/man/fr/man5
/usr/man/fr/man8
/usr/man/fr/man2
/usr/man/fr/man3
/usr/man/fr/man4
/usr/man/fr/man6
/usr/man/fr/man7
/usr/man/fr/man9
/usr/man/fr/mann

>>>>>>>>> TOTAL = 11

[root@localhost grepfind]# find2

liste des fichiers de taille nulle


==================================
./vide

ENSI/OMS/Intro OS/II1/ page 12


>>>>>>>> TOTAL = 1

liste des fichiers avec SUID-Bit=1


==================================

>>>>>>>>> TOTAL = 0

[root@localhost grepfind]#

Ecrire un script qui cherche tous les fichiers se trouvant dans une sous arborescence de racine le nom
d’un répertoire et appartenant à un groupe d’utilisateurs donné, et qui vous propose au travers d’un
menu soit de les afficher, de les détruire ou de les archiver.

#script find3 qui cherche tous les fichiers appartenant à un


# groupe donné et qui exécute une commande parmi une
# liste donnée dans un menu

function menuordre ()
{
echo "=========================================="
echo " A)rchiver "
echo " D)étruire "
echo " L)ister "
echo " Q)uitter "
echo "=========================================="
echo -n " votre choix : "
}

clear
echo -n "nom du groupe : "; read groupe
if ! grep "^$groupe:" /etc/group 1>/dev/null 2>/dev/null
then echo "erreur : nom du groupe erroné !!!"
exit 1
fi

echo -n "répertoire de recherche : "; read dossier


if ! test -d $dossier
then echo "erreur : répertoire inexisant ou inaccesible"
exit 2
fi

menuordre; read choix


case $choix in
[Aa]) echo -n "nom de l'archive : "; read archive
find $dossier -group $groupe | cpio -ocvB > $archive
;;
[Dd]) find $dossier -group $groupe -exec rm -f {} \;
;;
[Ll]) find $dossier -group $groupe -print
;;
*) echo "erreur commande inconnu"
exit 3
;;
esac

[root@localhost ss1rep]# find3


nom du groupe : omsaid
répertoire de recherche : .
==========================================

ENSI/OMS/Intro OS/II1/ page 13


A)rchiver
D)étruire
L)ister
Q)uitter
==========================================
votre choix : l
./fic1
./fic3
[root@localhost ss1rep]# ll
total 0
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic1
-rw-r--r-- 1 omsaid root 0 Mar 17 09:01 fic2
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic3
[root@localhost ss1rep]# find3
nom du groupe : root
répertoire de recherche : .
==========================================
A)rchiver
D)étruire
L)ister
Q)uitter
==========================================
votre choix : d
[root@localhost ss1rep]# ll
total 0
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic1
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic3
[root@localhost ss1rep]# find3
nom du groupe : omsaid
répertoire de recherche : .
==========================================
A)rchiver
D)étruire
L)ister
Q)uitter
==========================================
votre choix : A
nom de l'archive : archive
1 block
[root@localhost ss1rep]# ll
total 5
-rw-r--r-- 1 root root 5120 Mar 17 09:28 archive
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic1
-rw-r--r-- 1 omsaid omsaid 0 Mar 17 09:01 fic3
[root@localhost ss1rep]#

Ecrire un script utilisant la commande grep qui affiche les données complètes connues à propos d’un
utilisateur. Ce script signalera de plus si l’utilisateur en question posséde ou pas un mot de passe et si son
UID et GID sont valides.

#script gp1 cherchant si un utilisateur est connu du système


# et si oui affiche ses données caractéristiques présentes
# dans le fichier /etc/passwd à savoir son UID, GID, ...
#attention : doit également indiquer si l'utilisateur a ou non
# un mot de passe et renseigne sur la validité de UID et GID

clear
if test $# -ne 1
then echo erreur : un paramètres est attendu
echo usage : $0 nom_utilisateur

ENSI/OMS/Intro OS/II1/ page 14


exit 1
fi

user=$1
res=`grep "^$user:" /etc/passwd`
if ! test -z $res
then IFS=:
set $res
echo "infos de $user : UID=$3, GID=$4, HOME=$6, SHELL=$7"
if test -z $2
then echo " !!!! ATTENTION : pas de mot de passe"
fi
case $3 in
*[!0-9]*) echo " !!!!! ATTENTION : UID non valide" ;;
esac
case $4 in
*[!0-9]*) echo " !!!!! ATTENTION : GID non valide" ;;
esac
else echo "utilisateur $nom : inconnu"
fi

[root@localhost grepfind]# grep1


erreur : un paramètres est attendu
usage : ./grep1 nom_utilisateur
[root@localhost grepfind]# grep1 root
infos de root : UID=0, GID=0, HOME=/root, SHELL=/bin/bash
[root@localhost grepfind]# grep1 ouerghi
infos de ouerghi : UID=ttt, GID=506, HOME=/home/omsaid, SHELL=/bin/bash
!!!! ATTENTION : pas de mot de passe
!!!!! ATTENTION : UID non valide
[root@localhost grepfind]#

Ecrire un script utilisant la commande grep qui affiche les informations relatives à tous les utilisateurs
connus d’un groupe identifié par leur numéro.

#script grep2 affiche les informations concernant tous les


# utilisateurs d'un même groupe

if test $# -eq 0
then echo erreur : paramètres attendus
echo usage : $0 goupeId...
exit 1
fi

for grp
do echo "=================== traitement de $grp ===================="
case $grp in
*[!0-9]*) echo $grp n\'est pas un nombre ;;
*) ligne=`grep "^[^:]*:[^:]*:[^:]*:$grp:" /etc/passwd`
if test -n "$ligne"
then echo infos utilisateur du groupe $grp :
echo $ligne | tr " " "\n"
else echo pas d\'entrée pour le groupe $grp
fi;;
esac
done

[root@localhost grepfind]# grep2


erreur : paramètres attendus
usage : ./grep2 goupeId...

ENSI/OMS/Intro OS/II1/ page 15


[root@localhost grepfind]# grep2 0
=================== traitement de 0 ====================
infos utilisateur du groupe 0 :
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:
[root@localhost grepfind]# grep2 500 100
=================== traitement de 500 ====================
pas d'entrée pour le groupe 500
=================== traitement de 100 ====================
infos utilisateur du groupe 100 :
games:x:12:100:games:/usr/games:

Ecrire un script utilisant la commande grep qui prend comme paramètres une liste de noms de groupes et
qui affiche la liste de ses membres et les informations qui les concernent.

#script grep3 qui pend la liste des utilisateurs d'un groupe


# dont le nom est un paramètre donnée et
# qui affiche leurs informations respectives

if test $# -eq 0
then echo erreur : paramètres attendus
echo usage : $0 nom_groupe...
exit 1
fi

for grp
do echo ============= traitement de $grp ==================
membre=`grep "^$grp:" /etc/group |cut -f4 -d:`
if test -z "$membre"
then
echo liste des membres réduite à priori à $grp
if grep "^$grp:" /etc/passwd
then :
else echo $grp non utilisateur de ce système
fi
else
echo liste des membres du groupe $grp : $membre
IFS=,
set $membre
while test -n "$1"
do
grep "^$1" /etc/passwd
shift
done
fi
done

[root@localhost grepfind]# grep3 omsaid sys nogroup


============= traitement de omsaid ==================
liste des membres réduite à priori à omsaid
omsaid:x:501:502:omsaid:/home/omsaid:/bin/bash
============= traitement de sys ==================
liste des membres du groupe sys : root,bin,adm
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
adm:x:3:4:adm:/var/adm:
============= traitement de nogroup ==================

ENSI/OMS/Intro OS/II1/ page 16


liste des membres réduite à priori à nogroup
nogroup non utilisateur de ce système
[root@localhost grepfind]# grep3
erreur : paramètres attendus
usage : ./grep3 nom_groupe...
[root@localhost grepfind]#

ENSI/OMS/Intro OS/II1/ page 17


Ecrire un script awk qui affiche le contenu d’un fichier (supposé être valide). Chaque ligne de ce fichier
sera précédé par son numéro.

#script f1.awk qui affiche le contenu d'un fichier


# chaque ligne est précédé de son numéro

BEGIN {
system("clear")
print " contenu du fichier : ", ARGV[1]
print "=N°= =============contenu de la ligne====================="
}

{
print NR, ": ",$0
}

END {
print "===================================================fin===="
}

[root@localhost temp]# awk -f f1.awk fich.txt

contenu du fichier : fich.txt


=N°= =============contenu de la ligne=====================
1 : 1 ceci est un exemple
2 : 2 ceci est un exemple
3: 3
4 : ceci est un exemple
5 : 4 ceci est autre exemple
6:
7:
8 : ceci est un exemple : 5
9:
10 : ceci est un autre exemple : 6
11 :
===================================================fin====

[root@localhost temp]#

Ecrire un script awk qui utilise les variables prédéfinies pour afficher des champs particuliers du fichier
/etc/passwd.

#script f2.awk qui renseigne à propos


# des champs UID et GID du fichier /etc/passwd

BEGIN {
FS=":" #field separator"
print "\t le : ", strftime("%D")
print "=====début============================================="
}

#rien
{
print "username = " , $1," \t UID = ",$3, " \t GID = ", $4
}

END {
print "================================================fin===="

ENSI/OMS/Intro OS/II1/ page 18


}

[root@localhost temp]# cat /etc/passwd


root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
news:x:9:13:news:/var/spool/news:
uucp:x:10:14:uucp:/var/spool/uucp:
operator:x:11:0:operator:/root:
games:x:12:100:games:/usr/games:
gopher:x:13:30:gopher:/usr/lib/gopher-data:
ftp:x:14:50:FTP User:/home/ftp:
nobody:x:99:99:Nobody:/:
xfs:x:100:101:X Font Server:/etc/X11/fs:/bin/false
gdm:x:42:233::/home/gdm:/bin/bash
omsaid:x:501:502:omsaid:/home/omsaid:/bin/bash

[root@localhost temp]# awk -f f2.awk /etc/passwd


le : 03/14/03
=====début=============================================
username = root UID = 0 GID = 0
username = bin UID = 1 GID = 1
username = daemon UID = 2 GID = 2
username = adm UID = 3 GID = 4
username = lp UID = 4 GID = 7
username = sync UID = 5 GID = 0
username = shutdown UID = 6 GID = 0
username = halt UID = 7 GID = 0
username = mail UID = 8 GID = 12
username = news UID = 9 GID = 13
username = uucp UID = 10 GID = 14
username = operator UID = 11 GID = 0
username = games UID = 12 GID = 100
username = gopher UID = 13 GID = 30
username = ftp UID = 14 GID = 50
username = nobody UID = 99 GID = 99
username = xfs UID = 100 GID = 101
username = gdm UID = 42 GID = 233
username = omsaid UID = 501 GID = 502
================================================fin====
[root@localhost temp]#

Ecrire un script awk qui renseigne sur la validité des champs UID et GID du fichier /etc/passwd et qui
affiche le total des erreurs trouvées.

#script f3.awk qui renseigne à propos de la validité


# des champs UID et GID du fichier /etc/passwd

BEGIN {
FS=":" #field separator"
compteur=0
print "===== validité de UID et GID dans le fichier /etc/passwd"
}

ENSI/OMS/Intro OS/II1/ page 19


$3 !~ /^[0-9]+$/ || $4 !~ /^[0-9]+$/ {
compteur=compteur+1
print $1," avec un user ou groupe identifié non valide ???"
}

END {
print "\n\t\t\t $$$$ TOTAL = ", compteur
}

[root@localhost temp]# awk -f f3.awk /etc/passwd


===== validité de UID et GID dans le fichier /etc/passwd

$$$$ TOTAL = 0

[root@localhost temp]# cat /etc/passwd


root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
...........
ouerghi::ttt:506::/home/omsaid:/bin/bash

[root@localhost temp]# awk -f f3.awk /etc/passwd


===== validité de UID et GID dans le fichier /etc/passwd

ouerghi avec un user ou groupe identifié non valide ???

$$$$ TOTAL = 1
[root@localhost temp]#

Ecrire un script awk qui calcule itérativement les factorielles de 16 premiers entiers et qui affichera leur
résultat.

#script f4.awk affichant les 16 premières valeurs


# de la factorielle (je ne sais si on peut
# aller plus loin !!)

BEGIN {
FactN_1=1
print "n \t factorielle(n)"
print "0", "\t\t", FactN_1
for (i=1; i<=15; i++) {
FactN= i * FactN_1
print i, "\t\t", FactN
FactN_1= FactN
}
}

[root@localhost temp]# awk -f f4.awk


n factorielle(n)
0 1
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
10 3628800

ENSI/OMS/Intro OS/II1/ page 20


11 39916800
12 479001600
13 6.22702e+09
14 8.71783e+10
15 1.30767e+12
[root@localhost temp]#

Ecrire un script awk utilisant la structure de données tableau pour afficher le contenu d’un fichier ligne
par ligne dans l’ordre inverse de leur apparition initiale.

#script f5.awk utilisant des tableaux


# affiche le contenu du fichier dans l'ordre inverse

BEGIN { print "\t\taffichage inverse du contenu de : ",ARGV[1]


print "\t\t===============AVANT========================="
}

#rien
{ print "> ",$0
lignes[NR]=$0
}

END { print "\t\t===============APRES=========================="


for(i=NR;i>0; i--) { print "< ",lignes[i] }
print "\t\t=============================================="
}

[root@localhost temp]# awk -f f5.awk fich.txt


affichage inverse du contenu de : fich.txt
===============AVANT=========================
> 1 ceci est un exemple
> 2 ceci est un exemple
> 3
> ceci est un exemple
> 4 ceci est autre exemple
>
>
> ceci est un exemple : 5
>
> ceci est un autre exemple : 6
>
===============APRES==========================
<
< ceci est un autre exemple : 6
<
< ceci est un exemple : 5
<
<
< 4 ceci est autre exemple
< ceci est un exemple
< 3
< 2 ceci est un exemple
< 1 ceci est un exemple
==============================================
[root@localhost temp]#

Ecrire un script shell qui affiche certains champs du résultat de la commande date et ceux en recourant à
la commande awk.

#script f6.awk qui affiche certains champs du résultat

ENSI/OMS/Intro OS/II1/ page 21


# de la commande date en particulier l'heure actuelle
# l'équivalent en shell serait de procéder comme suit :
# set `date`
# echo $4 > xxx
# echo `cut -f1 -d: xxx` heures `cut -f2 -d: xxx` minutes
# rm -f xxx

date | awk '{ n=split($4, champ, ":")


print champ[1] " heures " champ[2] " minutes"
}'

[root@localhost temp]# date


ven mar 14 21:39:15 CET 2003
[root@localhost temp]# set `date`
[root@localhost temp]# v=$4
[root@localhost temp]# set $4
[root@localhost temp]# set `date`
[root@localhost temp]# echo $4 >xxx
[root@localhost temp]# echo `cut -f1 -d: xxx` heures `cut -f2 -d: xxx` minutes
21 heures 39 minutes
[root@localhost temp]# rm -f xxx
[root@localhost temp]# sh f6.awk
21 heures 40 minutes
[root@localhost temp]#

Ecrire un script awk qui réalise les même calculs que la commande wc (comptage du nombre de
caractères, mots et lignes d’un fichier) en utilisant les fonctions length, split, et en évitant de recourir aux
variables prédéfinies NF et NR.

#script f7.awk qui compte le nombre de caractères, mots et ligne d'un


# d'un fichier donné en paramètre
#attention : on n'utilisera pas les variables prédéfinies NF et NR
# NF = nb de mots par ligne du fichier (Number of Fields)
# NR = nb de lignes du fichier (Number of Row)

BEGIN {
print "le script awk équivalent à la commande $wc " ARGV[1] " donne :"
nblig=0
nbmot=0
nbcar=0
}

#rien
{
nblig=nblig + 1
nbmot=nbmot + split($0, t, " ")
nbcar=nbcar + length($0) + 1
}

END {
print "\tNombre de lignes : \t", nblig
print "\tNombre de mots : \t", nbmot
print "\tNombre de caractères : \t", nbcar
}

[root@localhost temp]# awk -f f7.awk fich.txt


le script awk équivalent à la commande $wc fich.txt donne :
Nombre de lignes : 11
Nombre de mots : 33
Nombre de caractères : 149

ENSI/OMS/Intro OS/II1/ page 22


[root@localhost temp]# wc fich.txt
11 33 149 fich.txt
[root@localhost temp]#

Ecrire un script awk qui affiche pour chaque ligne du fichier à traiter la somme de ses champs
numériques et en fin du parcours le total de ces totaux.

#script f8.awk qui calcule la somme des lignes d'un fichier


# dont les données sont des entiers

#NR: number of Row et NF : number of fields


BEGIN {
print "<Total> contenu du fichier "
print "=============================================="
}

NR>0 && NF>0 {


somParLigne=0
split($0, ligne, " ")
i=1
do { somParLigne+=ligne[i]
totalgeneral+= $i
i++
} while (i<=NF)
print "<"somParLigne">\t", $0
}

END {
print "==============================================="
print " Total Général = ", totalgeneral
}

[root@localhost temp]# awk -f f8.awk fich.ier


<Total> contenu du fichier
==============================================
<0> nom prénom note1 note2
<25> ali ali 12 13
<23> arbia arbi 10 13
<24> foulen filten 14 10
===============================================
Total Général = 72
[root@localhost temp]#

Ecrire un script awk qui affiche la moyenne des nombres contenus dans un fichier paramètre d’entrée du
script et présentés en colonnes.

#script f9.awk qui affiche la moyenne des nombres

BEGIN {
if (ARGC-1==0) {print "Aucun fichier de ce nom !!!" ; exit}
else print "contenu de fichier : ", ARGV[1]
}

{
split($0, champ, FS)
for(i=1; i<=NF; i++) {
printf("\t %s", champ[i])
T[i]+=champ[i]
}
printf("\n")

ENSI/OMS/Intro OS/II1/ page 23


}

END {
if (FILENAME) {
printf "valeurs moyennes de chaque colonne \n"
for (i=1; i<=NF; i++) printf("\t %5.2f ", T[i]/NR)
}
printf("\n")
}

[root@localhost temp]# awk -f f9.awk


Aucun fichier de ce nom !!!

[root@localhost temp]# awk -f f9.awk test.txt


contenu de fichier : test.txt
0 1 2 3
4 5 6 7
8 9 0 1
valeurs moyennes de chaque colonne
4.00 5.00 2.67 3.67
[root@localhost temp]#

Ecrire un script awk qui étant donné un nom de fichier et un motif donné, scrute le fichier ligne par ligne
pour indiquer si le motif en question y est présent ou pas.

#script f10.awk de recherche d'un motif dans un fichier

BEGIN {
printf("motif à rechercher : "); getline motif
printf("fichier concerné : "); getline fichier
}

#rien
{
getline < fichier
if ($0=="")
exit
else {
print $0
idx=index($0, motif)
if (idx==0)
printf("\t\t>>non trouvé")
else printf("\t\>>trouvé à l'indice : %d", idx)
}
}

END {
print "=======================fin========================"
}

[root@localhost temp]# cat fich.txt


1 ceci est un exemple
2 ceci est un exemple
3
ceci est un exemple
4 ceci est autre exemple

ceci est un exemple : 5

ENSI/OMS/Intro OS/II1/ page 24


ceci est un autre exemple : 6

[root@localhost temp]# awk -f f10.awk


motif à rechercher : exe
fichier concerné : fich.txt

1 ceci est un exemple


>>trouvé à l'indice : 15
2 ceci est un exemple
>>trouvé à l'indice : 15
3
>>non trouvé
ceci est un exemple
>>trouvé à l'indice : 13
4 ceci est autre exemple
>>trouvé à l'indice : 18
=======================fin========================
[root@localhost temp]#

Ecrire un script awk qui affiche toutes les occurrences d’un motif donné à rechercher dans un fichier
donné.

#script f11.awk de recherche de toutes les occurrences


# d'un motif dans un fichier
# on suppose que le fichier ne contient pas
# de lignes vides

BEGIN {
printf("motif à rechercher : ");getline motif
printf("nom du fichier : ");getline fichier
printf("\n==================début==================\n")
}

{
getline < fichier
if ($0=="")
exit
else
{
print $0
for(i=1;i<=length($0);i++) printf("-"); printf("\n")

ligne=$0
idx[0]=0; i=1
for(;;){
idnx=index(ligne,motif)
idx[i]=idx[i-1]+idnx; i++
if (idnx==0)
break
else
ligne=substr(ligne,idnx+1,length(ligne)-length(motif))
}

if (idx[1]!=0) { print "trouvé >>"


for(j=1;j<i-1;j++) printf("\t\>%d",idx[j])
}
else print "non trouvé !!"

ENSI/OMS/Intro OS/II1/ page 25


}

END {
print "=======================fin========================"
}

[root@localhost temp]# cat texte


ceci est un texte pour montrer un exemple
d'utilisation des fonctions length, substr, index
qui sont définies dans awk.
Awk : un sympatique outil pour scripting
a+
oms
[root@localhost temp]# awk -f f11.awk
motif à rechercher : e
nom du fichier : texte

==================début==================

ceci est un texte pour montrer un exemple


-----------------------------------------
trouvé >>
>2 >6 >14 >17 >29 >35 >37 >41
d'utilisation des fonctions length, substr, index
-------------------------------------------------
trouvé >>
>16 >30 >48
qui sont définies dans awk.
---------------------------
trouvé >>
>16
Awk : un sympatique outil pour scripting
----------------------------------------
trouvé >>
>19
a+
--
non trouvé !!

oms
---
non trouvé !!

=======================fin========================
[root@localhost temp]#

ENSI/OMS/Intro OS/II1/ page 26