Tous les shells qui seront créés par la suite devront avoir le droit d'exécution correctement positionné, au moins pour leur propriétaire.
Écrivez un shell qui permette de chercher si un
utilisateur d'un nom donné existe sur votre machine,
en affichant sa référence complète
(c'est-à-dire sans aucun filtrage).
Le nom recherché sera passé comme
paramètre au shell.
La recherche portera dans le fichier
/etc/passwd.
# Fichier "infouser1.sh"
#!/bin/sh
grep $1 /etc/passwd
Modifiez ce script shell pour qu'il teste si un paramètre est bien passé en ligne. En cas d'erreur (aucun paramètre ou plus d'un), un message sera affiché expliquant la bonne syntaxe à suivre.
Retour# Fichier "infouser2.sh"
#!/bin/sh
if test $# -ne 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 uid
exit 1
fi
grep $1 /etc/passwd
Modifiez encore ce shell pour qu'il teste si l'utilisateur demandé existe sur votre machine. En cas d'absence, affichez un message d'avertissement.
Retour# Fichier "infouser3.sh"
#!/bin/sh
if test $# -ne 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 [uid]
exit 1
fi
if test `grep $1 /etc/passwd | wc -l` -lt 1
then
echo L\'utilisateur $1 n\'est pas créé sur cette machine.
exit 2
fi
grep $1 /etc/passwd
Par défaut, le shell s'arrête avec un statut à zéro, c'est
pourquoi une ligne exit 0 à la fin du programme
est superflue.
Le test effectué est -lt 1 (plus petit que 1),
mais on aurait tout aussi bien pu faire -eq 0.
Le texte de sortie contient des \', pour que le
shell n'interprète pas ce caractère spécial comme une quote,
mais comme une apostrophe (texte normal, et pas caractère
spécial).
On aurait pu aussi utiliser un test plus simple sur le
résultat de grep $1 /etc/passwd, et le
transformer en if test ! $?.
Pour cette partie du TP, il vous faut d'abord récupérer
les deux corpus suivants :
corpus1.xml.gz
corpus2.xml.gz
Ces deux fichiers contiennent 25 notices en XML Dilib, leur exploration
préparatoire est conseillée.
Écrivez un script shell qui édite le
pourcentage de résumés, pour chacun des deux
corpus, en passant le nom de fichier en
paramètre.
Les fichiers ne devront
jamais être décompressés sur
disque.
L'élément résumé se nomme
fC01.
# Fichier "resume1.sh"
#!/bin/sh
if test $# -ne 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 fichier
exit 1
fi
NB_LIGNES=`gzcat $1|wc -l`
NB_RESUMES=`gzcat $1|grep fC01|wc -l`
NB_RES_100=`expr 100 \* $NB_RESUMES`
POURCENTAGE=`expr $NB_RES_100 / $NB_LIGNES`
echo Pourcentage de notices avec résumé dans $1: ${POURCENTAGE}%
N'oubliez pas de banaliser l'opérateur de multiplication,
sinon expr ne comprendra pas ce que vous
demandez (man expr pour plus de détails).
gzcat est utilisé, mais on pourrait aussi
utiliser gunzip -c.
Modifiez le shell précédent pour qu'il teste
l'existence du fichier demandé avant traitement, puis
pour qu'il sorte les résultats dans un fichier
nommé resultatsfC01.txt.
# Fichier "resume2.sh"
#!/bin/sh
if test $# -ne 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 fichier
exit 1
fi
if test ! -f $1
then
echo $1 "n'existe pas (ou n'est pas un fichier)."
exit 2
fi
NB_LIGNES=`gzcat $1|wc -l`
NB_RESUMES=`gzcat $1|grep fC01|wc -l`
NB_RES_100=`expr 100 \* $NB_RESUMES`
POURCENTAGE=`expr $NB_RES_100 / $NB_LIGNES`
echo Pourcentage de notices avec résumé dans $1: ${POURCENTAGE}% > resultatsfC01.txt
Cette fois, on a mis la chaîne contenant les apostrophes (caractère spécial) entre guillemets pour les banaliser.
Écrivez un script shell qui, pour les deux corpus et
en testant l'existence du fichier demandé, calcule le
pourcentage de notices sans résumé, le
pourcentage de notices de type périodique et le
pourcentage de notices de langue française.
La liste des éléments à prendre en
compte sera passée en paramètres en ligne au
shell et ceux-ci seront traités en boucle avec un
while.
Les statistiques obtenues seront
récupérées dans le fichier
resultatsMulti.txt.
Les éléments à utiliser sont
fA60 pour le type de document (P
pour périodique) et fA23 pour la langue
(FRE pour la langue française).
# Fichier "resume3.sh"
#!/bin/sh
if test $# -lt 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 fichier...
exit 1
fi
rm -f resultatsMulti.txt
while test $# -ne 0
do
if test ! -f $1
then
echo $1 "n'existe pas (ou n'est pas un fichier)."
exit 2
fi
echo ----------- >> resultatsMulti.txt
echo $1 >> resultatsMulti.txt
echo ----------- >> resultatsMulti.txt
NB_LIGNES=`gzcat $1|wc -l`
NB_SANS_RESUME=`gzcat $1|grep -v fC01|wc -l`
NB_PERIODIQUES=`gzcat $1|grep "fA60><s1>P</"|wc -l`
NB_FRANCAIS=`gzcat $1|grep "fA23 i1=\"01\"><s0>FRE</"|wc -l`
NB_SANS_RES_100=`expr 100 \* $NB_SANS_RESUME`
POURCENTAGE_SANS_RES=`expr $NB_SANS_RES_100 / $NB_LIGNES`
echo "Pourcentage de notices sans résumé : ${POURCENTAGE_SANS_RES}%" \
>> resultatsMulti.txt
NB_PERIO_100=`expr 100 \* $NB_PERIODIQUES`
POURCENTAGE_PERIODIQUES=`expr $NB_PERIO_100 / $NB_LIGNES`
echo "Pourcentage de notices de type périodique : ${POURCENTAGE_PERIODIQUES}%" \
>> resultatsMulti.txt
NB_FRANCAIS_100=`expr 100 \* $NB_FRANCAIS`
POURCENTAGE_FRANCAIS=`expr $NB_FRANCAIS_100 / $NB_LIGNES`
echo "Pourcentage de notices françaises : ${POURCENTAGE_FRANCAIS}%" \
>> resultatsMulti.txt
shift
done
shift est utilisé pour parcourir tous les
paramètres et considérer chacun d'entre eux comme le
paramètre numéro 1.
Le rm -f resultatsMulti.txt est là pour
éviter la concaténation des résultats avec ceux des
exécutions précédentes du même script.
Pour plus de précision, on pourrait utiliser la commande
DILIB SgmlSelect plutôt que
grep, pour sélectionner les notices
françaises (en effet, si l'attribut i1 changeait, la
commande de comptage deviendrait plus compliquée avec
grep).
Le caractère \ en fin de ligne permet de
passer à la ligne sans interrompre la commande. C'est une
facilité de présentation.
Modifiez le shell précédent pour que le fichier résultat soit compressé au choix (Oui/Non).
Retour# Fichier "resume4.sh"
#!/bin/sh
if test $# -lt 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 [-z] fichier...
exit 1
fi
rm -f resultatsMulti.txt*
COMPRESSION=0
while test $# -ne 0
do
case $1 in
-z ) COMPRESSION=1 ;;
* )
if test ! -f $1
then
echo $1 "n'existe pas (ou n'est pas un fichier)."
exit 2
fi
echo ----------- >> resultatsMulti.txt
echo $1 >> resultatsMulti.txt
echo ----------- >> resultatsMulti.txt
NB_LIGNES=`gzcat $1|wc -l`
NB_SANS_RESUME=`gzcat $1|grep -v fC01|wc -l`
NB_PERIODIQUES=`gzcat $1|grep "fA60><s1>P</"|wc -l`
NB_FRANCAIS=`gzcat $1|grep "fA23 i1=\"01\"><s0>FRE</"|wc -l`
NB_SANS_RES_100=`expr 100 \* $NB_SANS_RESUME`
POURCENTAGE_SANS_RES=`expr $NB_SANS_RES_100 / $NB_LIGNES`
echo "Pourcentage de notices sans résumé : ${POURCENTAGE_SANS_RES}%" \
>> resultatsMulti.txt
NB_PERIO_100=`expr 100 \* $NB_PERIODIQUES`
POURCENTAGE_PERIODIQUES=`expr $NB_PERIO_100 / $NB_LIGNES`
echo "Pourcentage de notices de type périodique : ${POURCENTAGE_PERIODIQUES}%" \
>> resultatsMulti.txt
NB_FRANCAIS_100=`expr 100 \* $NB_FRANCAIS`
POURCENTAGE_FRANCAIS=`expr $NB_FRANCAIS_100 / $NB_LIGNES`
echo "Pourcentage de notices françaises : ${POURCENTAGE_FRANCAIS}%" \
>> resultatsMulti.txt
;;
esac
shift
done
if test $COMPRESSION -eq 1
then
touch resultatsMulti.txt
gzip resultatsMulti.txt
fi
L'utilisation du case à l'intérieur du
while autorise l'apparition de l'option
-z n'importe où sur la ligne de commande.
L'instruction touch resultatsMulti.txt
permet, lorsqu'aucun fichier n'a été passé en paramètre,
et que l'option -z a été sélectionnée, de ne
pas avoir de message d'erreur: resultatsMulti.txt:
No such file or directory. On ne peut pas
compresser un fichier qui n'existe pas. touch
modifie la date de dernière modification d'un fichier,
mais aussi elle crée un fichier lorsqu'il
n'existe pas.
Reprenez le shell précédent pour que le
fichier résultat soit nommé avec une
indication de date/heure à l'aide de la commande
date d'Unix (notion de mise à
jour).
ATTENTION ! On considèrera le fichier
corpus2.xml.gz comme une mise à jour de
corpus1.xml.gz. Leur différence de
nommage pourra par exemple être liée
plutôt à l'heure qu'à la date.-->
# Fichier "resume5.sh"
#!/bin/sh
if test $# -lt 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 [-z] fichier...
exit 1
fi
NOM_FICHIER=resultatsMulti`date '+%H%M%S'`.txt
COMPRESSION=0
while test $# -ne 0
do
case $1 in
-z ) COMPRESSION=1 ;;
* )
if test ! -f $1
then
echo $1 "n'existe pas (ou n'est pas un fichier)."
exit 2
fi
echo ----------- >> $NOM_FICHIER
echo $1 >> $NOM_FICHIER
echo ----------- >> $NOM_FICHIER
NB_LIGNES=`gzcat $1|wc -l`
NB_SANS_RESUME=`gzcat $1|grep -v fC01|wc -l`
NB_PERIODIQUES=`gzcat $1|grep "fA60><s1>P</"|wc -l`
NB_FRANCAIS=`gzcat $1|grep "fA23 i1=\"01\"><s0>FRE</"|wc -l`
NB_SANS_RES_100=`expr 100 \* $NB_SANS_RESUME`
POURCENTAGE_SANS_RES=`expr $NB_SANS_RES_100 / $NB_LIGNES`
echo "Pourcentage de notices sans résumé : ${POURCENTAGE_SANS_RES}%" \
>> $NOM_FICHIER
NB_PERIO_100=`expr 100 \* $NB_PERIODIQUES`
POURCENTAGE_PERIODIQUES=`expr $NB_PERIO_100 / $NB_LIGNES`
echo "Pourcentage de notices de type périodique : ${POURCENTAGE_PERIODIQUES}%" \
>> $NOM_FICHIER
NB_FRANCAIS_100=`expr 100 \* $NB_FRANCAIS`
POURCENTAGE_FRANCAIS=`expr $NB_FRANCAIS_100 / $NB_LIGNES`
echo "Pourcentage de notices françaises : ${POURCENTAGE_FRANCAIS}%" \
>> $NOM_FICHIER
;;
esac
shift
done
if test $COMPRESSION -eq 1
then
touch $NOM_FICHIER
gzip $NOM_FICHIER
fi
Écrivez un shell qui, reprenant les exercices
précédents, calcule les statistiques sur le
fichier corpus1.xml.gz, puis stocke les
résultats en compressé. Ensuite, le même
traitement sera porté sur corpus2.xml.gz
considéré comme une mise à jour
cumulative des statistiques (c'est-à-dire qu'il n'y
aura qu'un seul fichier résultat repris puis
écrasé au second traitement).
# Fichier "resume6.sh"
#!/bin/sh
if test $# -lt 1
then
echo Mauvais nombre de parametres.
echo
echo Usage: $0 [-z] fichier...
exit 1
fi
NOM_FICHIER=resultatsMulti`date '+%H%M%S'`.txt
COMPRESSION=0
CUMUL_NB_LIGNES=0
CUMUL_NB_SANS_RESUME=0
CUMUL_NB_PERIODIQUES=0
CUMUL_NB_FRANCAIS=0
while test $# -ne 0
do
case $1 in
-z ) COMPRESSION=1 ;;
* )
if test ! -f $1
then
echo $1 "n'existe pas (ou n'est pas un fichier)."
exit 2
fi
echo ----------- >> $NOM_FICHIER
echo $1 >> $NOM_FICHIER
echo ----------- >> $NOM_FICHIER
NB_LIGNES=`gzcat $1|wc -l`
NB_SANS_RESUME=`gzcat $1|grep -v fC01|wc -l`
NB_PERIODIQUES=`gzcat $1|grep "fA60><s1>P</"|wc -l`
NB_FRANCAIS=`gzcat $1|grep "fA23 i1=\"01\"><s0>FRE</"|wc -l`
CUMUL_NB_LIGNES=`expr $CUMUL_NB_LIGNES + $NB_LIGNES`
CUMUL_NB_SANS_RESUME=`expr $CUMUL_NB_SANS_RESUME + $NB_SANS_RESUME`
CUMUL_NB_PERIODIQUES=`expr $CUMUL_NB_PERIODIQUES + $NB_PERIODIQUES`
CUMUL_NB_FRANCAIS=`expr $CUMUL_NB_FRANCAIS + $NB_FRANCAIS`
NB_SANS_RES_100=`expr 100 \* $NB_SANS_RESUME`
POURCENTAGE_SANS_RES=`expr $NB_SANS_RES_100 / $NB_LIGNES`
echo "Pourcentage de notices sans résumé : ${POURCENTAGE_SANS_RES}%" \
>> $NOM_FICHIER
NB_PERIO_100=`expr 100 \* $NB_PERIODIQUES`
POURCENTAGE_PERIODIQUES=`expr $NB_PERIO_100 / $NB_LIGNES`
echo "Pourcentage de notices de type périodique : ${POURCENTAGE_PERIODIQUES}%" \
>> $NOM_FICHIER
NB_FRANCAIS_100=`expr 100 \* $NB_FRANCAIS`
POURCENTAGE_FRANCAIS=`expr $NB_FRANCAIS_100 / $NB_LIGNES`
echo "Pourcentage de notices françaises : ${POURCENTAGE_FRANCAIS}%" \
>> $NOM_FICHIER
;;
esac
shift
done
if test $CUMUL_NB_LIGNES -gt 0
then
NB_SANS_RES_100=`expr 100 \* $CUMUL_NB_SANS_RESUME`
POURCENTAGE_SANS_RES=`expr $NB_SANS_RES_100 / $CUMUL_NB_LIGNES`
NB_PERIO_100=`expr 100 \* $CUMUL_NB_PERIODIQUES`
POURCENTAGE_PERIODIQUES=`expr $NB_PERIO_100 / $CUMUL_NB_LIGNES`
NB_FRANCAIS_100=`expr 100 \* $CUMUL_NB_FRANCAIS`
POURCENTAGE_FRANCAIS=`expr $NB_FRANCAIS_100 / $CUMUL_NB_LIGNES`
echo --------------- CUMUL >> $NOM_FICHIER
echo "Pourcentage de notices sans résumé : ${POURCENTAGE_SANS_RES}%" \
>> $NOM_FICHIER
echo "Pourcentage de notices de type périodique : ${POURCENTAGE_PERIODIQUES}%" \
>> $NOM_FICHIER
echo "Pourcentage de notices françaises : ${POURCENTAGE_FRANCAIS}%" \
>> $NOM_FICHIER
fi
if test $COMPRESSION -eq 1
then
touch $NOM_FICHIER
gzip $NOM_FICHIER
fi
On teste le nombre de lignes cumulées, car dans le cas où
aucun fichier n'aurait été traité, la variable
CUMUL_NB_LIGNES vaudrait zéro, et
occasionnerait une erreur lors de la division!