Vérifier / ajouter / forcer une ligne de texte
Problème:
Je voudrais être sûr que le fichier de configuration toto.conf du programme toto ait bien la ligne "ligne hyper importante = moi personnellement je", que la ligne n'apparaisse qu'une seule fois et que ce soit exactement celle-là si elle y est déjà.
Solution:
Je tombe régulièrement sur ce genre de problème et suite à un fil, je place la solution que j'utilise maintenant régulièrement.
Code:
1 2 3 4 5 6 7 8 9 10
| line="ligne hyper importante = moi personnellement je"
selection="^ligne hyper importante = "
confFile="toto.conf"
awk -v l="$line" -v s="$selection" '
{
if ($0 !~ /^#/ && $0 ~ s) {if (!done) {print l; done=1}}
else {print}
}
END {if (!done) {print l}}' $confFile > $confFile.new
mv -f $confFile.new $confFile.new |
Explications:
- Les trois premières lignes initialisent des variables. Pas important.
- La première partie de awk permet de ne pas tenir compte des commentaires et de forcer la ligne si elle est trouvée. Dans ce dernier cas, les éventuelles lignes suivantes identiques sont supprimées.
- La dernière partie de awk ajoute la ligne si elle n'a pas été détectée.
Correction pour truc et astuces
Citation:
Envoyé par
jmelyn
Exemple 1: L'effondrement du mur de Berlin, c'était quel jour?
D'abord, petit tour sur Wikipépia me donne le 09 novembre 1989.
Puis, le
man de
date -d m'indique comment passer la date en nombre de secondes.
Ensuite le
man de
awk au châpitre
Time functions me propose
strftime() qui me va bien.
Enfin, le
man de
strftime, fonction C, me fournit le bon argument:
%A.
Code:
1 2
| date -d 1989-11-09 +%s | awk '{print strftime("%A", $0)}'
Thursday |
Pourquoi pas simplement:
Code:
1 2
| $ date -d 1989-11-09 +%A
jeudi |
Ou, en anglais:
Code:
1 2
| $ LANG=C date -d 1989-11-09 +%A
Thursday |
Créer un lockfile - verrou
Si on veut qu'un script ne tourne pas s'il est déjà lancé par un autre utilisateur. Ou bien si on souhaite qu'un script ne se lance pas si un autre est toujours occupé, classiquement, on peut créer un "lock file" qui est détruit quand le script se termine et tester son existence. Il y a plus simple: la commande lockfile.
Un petit exemple que vous pourrez développer:
Exemple, premier processus:
Code:
lockfile /tmp/lock; sleep 10; rm -f /tmp/lock
Le second processus attendra tant que le premier est occupé:
Code:
lockfile /tmp/lock && echo "Enfin! C'est pas trop tôt..."; rm -f /tmp/lock
Le second processus s'interrompt si le premier est occupé:
Code:
lockfile -r0 /tmp/lock && echo "Enfin! C'est pas trop tôt..."; rm -f /tmp/lock
Voir aussi les autres options telles que sleeptime.
Source:
http://www.unix.com/shell-programmin...#post302364124
getopts : Mutualisation des options dites "communes"
En créant de multiples scripts, j'ai eu envie des créer de l'aide en ligne, d'afficher leur version, ou de les lancer en version debug, plus certaines particularités pour certains scripts. La commande getops fût la bienvenue. Plusieurs étapes ont vu le jour dans mon idée, dont voici la première :
- mutualisation des options dites « communes » (ex : -h, -x) en les incluant dans un script de style bibliothèque.
Mutualisation des options :
Ci-dessous, la commande getops lançant la bibliothèque d'options communes :
Code:
1 2 3 4 5 6 7 8 9
| while getopts abcdefghijklmnopqrstivwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ OPTION
do
case $OPTION in
a) f_a_all # traitements (ici lancement de la function f_a_all)
;;
*) . /usr/expl/proc/BIBLIOTHEQUES/getopts.lib
;;
esac
done |
La bibliothèque des options communes (getopts.lib) :
Code:
1 2 3 4 5 6 7 8 9 10
| case $OPTION in
h) help # traitements (ici lancement de la function help)
;;
v) version # traitements (ici lancement de la function version)
;;
x) set x # traitements (ici set x)
;;
*) echo "Erreur : l'option courte \"$OPTION\" est inexistante"
exit
esac |
PS : dans cette exemple, les options a, h, v et x sont reconnues. Les autres options afficheront :
l'option courte \"$OPTION\" est inexistante"
Attention : la bibliothèque doit être lancée avec le point devant « . »
Dans cet exemple, nous pouvons utiliser l'option -x au lieu d'ajouter la commande "set -x" dans le script et évite son modification.
Cela permet une plus grande souplesse dans les ajouts, modifications ou suppressions d'options communes (ex : ajout d'options longues dans ma seconde étape).
getopts en ksh : les options longues "sans arguments"
Nous voilà dans ma seconde étape, afin de pallier au problème des options longues, j'ai recours à l'utilisation du tiret comme option. Je ne suis pas le premier à trouver une solution, mais voici ma solution (en 2 points):
- ajout d'une option acceptant les arguments "-:"
- utilisation de la commande case pour les options longues
getopts dans le script :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| while getopts abcdefghijklmnopqrstivwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-: OPTION
do
case $OPTION in
a) f_a_all # Lancement de function f_a_all
;;
d) f_b_description # Lancement de function f_d_description
;;
-) case $OPTARG in
all) f_a_all # Lancement de la function f_a_all
;;
description) f_b_description # Lancement de function f_d_description
;;
*) . /usr/expl/proc/BIBLIOTHEQUES/getopts.lib
;;
esac
*) . /usr/expl/proc/BIBLIOTHEQUES/getopts.lib
;;
esac
done |
et pour les options communes :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| case $OPTION in
h) help # traitements (ici lancement de la function help)
;;
x) set x # traitements (ici set x)
;;
-) case $OPTARG in
debug) set -x
;;
help) help
;;
*) echo "Erreur : l'option longue \"$OPTARG\" est inexistante"
exit
;;
esac
*) echo "Erreur : l'option longue \"$OPTARG\" est inexistante"
exit
;;
esac |
La troisième et dernière étape sera "getops en ksh - les options longues avec arguments".
getopts en ksh : les options longues "avec arguments"
Nous voici donc dans la troisième étape (complément des options longues sans arguments) :
Afin de pouvoir récupérer les arguments des options longues, il faut prétraiter les paramètres afin de les avoir sur plusieurs lignes (au lieu d’une seule). L’action d’aller à la ligne doit se faire uniquement lorsque nous rencontrons un tirer « - »
Prétraitement avant getopts :
Code:
1 2 3 4 5 6 7 8 9
| for i in $*
do
if [ "$(echo $i | cut -c1)" = "-" ]
then
PARAMETRES="$PARAMETRES\n$i"
else
PARAMETRES="$PARAMETRES $i"
fi
done |
Cela nous permet, dans l’exemple ci-dessous :
Code:
1 2 3 4 5 6
| courriel --objet "TEST" --message "Ceci est un test" --destinataire "toto@huit.fr"
echo $PARAMETRES
--objet TEST
--message Ceci est un test
--destinataire toto@huit.fr |
Il suffit ensuite de lui passer un grep en prenant à partir du second champ, comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
-) case $OPTARG in
destinataire*) CIBLE=$(echo $PARAMETRES | grep "\-\-destinataire" | cut -d" " -f2-)
shift
;;
message) MESSAGE="$(echo $PARAMETRES | grep "\-\-message" | cut -d" " -f2-)"
shift
;;
objet) OBJET="$(echo $PARAMETRES | grep "\-\-objet" | cut -d" " -f2-)"
shift
;;
esac |
et le tour est joué !!!!
Code:
1 2 3 4 5 6 7 8
| echo $CIBLE
toto@huit.fr
echo $MESSAGE
Ceci est un test
echo $OBJET
TEST |