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 -c -i seulement) -l -n -e motif -f fichier
seules les lignes ne contenant pas le motif sont affichées; seul le nombre de lignes satisfaisantes est affiché ignore la distinction minuscule/majuscule dans les comparaisons (grep
seules les noms de fichiers contenant le motif sont affichés; numérote les lignes affichées; lorsque le motif commence par un tiret; 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 $ grep From $MAIL $ grep From $MAIL¦ grep - v marie $ grep -c marie $HOME/lib/annuaire $ who¦ grep marie $ ls¦ grep -v temp
cherche variable dans les sources affiche les en-têtes des messages autre que marie trouve le numéro de marie dans l'annuaire est-elle connectée? les noms de fichiers ne contenant temp
expressions régulières de grep et fgrep (par ordre décroissant de précédence)
c \c ^ $ . [...] [^...] \n r*
tout caractère non spécial 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 ... ce qui a été identifié par la nième sous expression \(...\) (grep seulement) zéro ou plus occurrences de r
ENSI/OMS/Intro OS/II1/ page 1
r+ r? r1¦r2 \ (r \) (r)
une ou plus occurrences de r zéro ou une occurrence de r r1 suivi de r2 sous expression r repérée (grep seulement); peut être imbriqué expression régulière r2 (egrep seulement), peut être imbriqué
Exemples $ grep '^From'$MAIL $ ls-1¦ grep '^d' $ ls -1 ¦ grep'^.......rw' $ grep '^[^:]*::' /etc/passwd
imprime toutes les lignes commençant par From imprime seulement les lignes décrivant un répertoire imprime les fichiers qui peuvent être lus ou écrits par tous 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> -user <nom> -atime <n> -mtime <n> -newer <fichier> -type <x>
-perm <octal> -links <n> -group <nom> -size <n> - exec commande
-print - inum <n> -\(expression\)
Remarque
vrai si le motif s'applique sur le nom du fichier courant; vrai si le fichier courant appartient à l'utilisateur nom; vrai si le fichier a été utilisé dans les n derniers jours; peu utilisable; vrai si le fichier a été modifié dans les n derniers jours; vrai si le fichier courant a été modifié plus récemment que fichier; 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);
vrai si les permissions du fichier correspondent au nombre octal donné; vrai si le fichier a n liens; vrai si le groupe propriétaire du fichier est nom; vrai si le fichier contient <n> blocs; 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 {}; le nom de fichier doit être imprimé; vrai si le i-noeud du fichier à pour numéro n; a pour valeur booléenne celle de l'expression parenthésée.
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 -u -o <fichier> -d -f -n -i -r -b -t<x> clé
Exemples
sort + 1 -2 f
(check) vérifie que le fichier est trié; la sortie n'existe que si le fichier n'est pas trié; (unique) ne garde qu'une ligne parmi toutes celles qui ont la même clé; (output) envoie la sortie sur <fichier> (dictionary) les comparaisons ne se font qu'avec les lettres, les chiffres et les blancs; lettre minuscules et majuscules sont confondues; clé numérique (signée éventuellement); les caractères dont le code ASCII est extérieur à l'intervalle octal 040-0176 sont ignorés; renverser l'ordre du tri; ignorer les blancs en début de champ; le délimiteur de champ dans les lignes est le caractère <x> et non le TAB 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é.
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, 0
1
01/03/70, 2
cISET 3
champs + 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
Publicité
adresses sauf a et i (zéro ou une).
a\ <texte> b <etiq> c\ d i\ l q r fichier s/<anc>/<nouv>/ f : substitue l'expression régulière <anc> par la chaîne de substitution nouv. f est un indicateur :
ajoute des lignes à la sortie jusqu'à la première ligne ne se terminant pas par \ saut à la commande : <etiq> remplace des lignes comme pour a détruit la ligne courante; lit la suivante insère le texte avant la prochaine sortie imprime la ligne termine lit fichier et copie son contenu en sortie
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> w <fichier> y/<ch1>/<ch2>/
= ! commande-sed { et } N
branchement à : <etiq> si la dernière substitution a réussi écrit dans <fichier> 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 la commande est effectuée sur les lignes non sélectionnées associe à un espace d'adressage une liste de commandes la ligne courante est ajoutée au tampon qui en contient alors deux
ENSI/OMS/Intro OS/II1/ page 4
D P h H g G x
détruit le début du tampon jusqu'à la première fin de ligne include affiche le début du tampon jusqu'à la première fin de ligne incluse le tampon est copié dans le tampon auxilière dont le contenu est détruit le tampon est ajouté dans le tampon auxilière; le séparateur est la fin de ligne le tampon auxilière est copié dans le tampon dont le contenu est détruit le tampon auxilière est ajouté dans le tampon ;; le séparateur est la fin de ligne é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 slim
tty2 tty4
Sep Sep
29 29
11 : 53 12 : 15
$ who ¦ awk ' {print $1, $5} ‘ rim slim
11 : 53 12 : 15
imprime les noms et heurs de connexions
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 FS NF NR OFMT OFS ORS
nom du fichier courant d'entrée séparateur de champs dans l'enregistrement courant nombre de champs dans l'enregistrement courant numéro de l'enregistrement courant format de sortie des nombres (défaut %g, voir printf ...) séparateur de champs de sortie ( par défaut, un espace) 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 ~/$/ $2!~ /./ length ($2) == 0 2 ème champ de longueur nulle
2ème champ vide 2 ème champ identique à la chaîne vide 2 ème champ ne contient aucun caractère
$ 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.
Publicité
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. opérateur de concaténation de chaînes plus, moins multiplication, division, reste incrémentation, décrémentation (préfixé ou postfixé)
&& ! >>=< <= ==!=~!~ <espace> + - * / % ++ --
Les fonctions
cos (expr) exp (expr) getline() index (s1, s2) int (expr) length (s) log (expr) sin (expr)
cosinus de expr exponentielle de expr lit la ligne suivante; retourne 0 si la fin de fichier, 1 sinon position de la chaîne s1 dans la chaîne s2 partie entière de expr longueur de la chaîne s. Sans argument, $0 est pris comme argument. logarithme naturel de expr sinus de expr
ENSI/OMS/Intro OS/II1/ page 7
split (s, a, c) sprintf(fmt,...) substr(s, m, n)
découpe s en a [1], a[2], ..., a [n] suivant le délimiteur c ( par défaut la valeur de FS) formate ... en accord avec la spécification fmt 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
getline
getline var
getline < "fichier"
getline var < "fichier
"commande" | getline
"commande" | getline var
Lit et parse une nouvelle ligne depuis le fichier courant dans les variables standard $0, $1, etc.
Lit une nouvelle ligne depuis le fichier courant vers la variable var. La ligne n'est pas parsée.
$0, $1 ... , NR, FNR, NF
juste var
Lit et parse une nouvelle ligne depuis le fichier "fichier" dans les variables standard $0, $1, etc.
$0, $1 ..., NF
Lit une nouvelle ligne depuis le fichier "fichier" vers la variable var. La ligne n'est pas parsée.
juste var
Lit une nouvelle ligne dans le tube i.e. depuis la sortie standard de commande et vers les variables standard $0, $1, etc.
$0, $1 ..., NF
Lit une nouvelle ligne dans le tube i.e. depuis la sortie standard de commande et vers la variablevar.
juste var
- 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 continue exit
sortie de la boucle courant poursuivre à l'itération suivante de la boucle 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 }
it ($i == $(i-1)) printf " double %s, fichier %s, ligne %s \n", $i, FILENAME, NR if (NF >0) dernmot=SNF
NF<0 {
} ' $*
$
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
Publicité
======================================================= 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 # # #attention : doit également indiquer si l'utilisateur a ou non #
et si oui affiche ses données caractéristiques présentes dans le fichier /etc/passwd à savoir son UID, GID, ...
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 IFS=: then set $res echo "infos de $user : UID=$3, GID=$4, HOME=$6, SHELL=$7" if test -z $2 then fi case $3 in *[!0-9]*) echo " !!!!! ATTENTION : UID non valide" ;; esac case $4 in *[!0-9]*) echo " !!!!! ATTENTION : GID non valide" ;; esac echo "utilisateur $nom : inconnu"
echo " !!!! ATTENTION : pas de mot de passe"
else 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" echo pas d\'entrée pour le groupe $grp
else 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
else
echo liste des membres réduite à priori à $grp if grep "^$grp:" /etc/passwd then : else echo $grp non utilisateur de ce système fi
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
Publicité
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 : =================================