|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Salut à tous!
J'ai un projet pour lequel je coince un peu, et j'ai besoin de votre aide. En fait je dois ecrire un script shell sh qui émule les fonctionnalites basiques d'une base de données, qui sera contenue dans un fichier nomé sh.db par exemple. Le script doit être écrit en sh et s'exécuter sous UNIX. Vu le délai très court pour rendre mon projet(ce weekend) et que je ne suis pas très callé en programmation shell, je viens vers vous. Voici les fonctionnalités demandées: Pouvoir insérer une clé dans le fichier via la commande(put) ./script.sh put <key> <valeur> (si la clé existe déjà la valeur est écrasée); supprimer une entrée de la base : ./script.sh del <key> <valeur>; afficher les valeurs qui matchent avec une expression(comme avec un grep): ./script.sh select <expr>; vider la base de donnees sans supprimer le fichier: ./script.sh flush; passer le fichier en parametre avec l'option -f; creer le fichier s'il est passe en parametre et n'existe pas. Donc le script prendra des options et des parametres; et les entrees sont juste Clé=Valeur. Pour l'insertion et la suppresion, rien ne dois être affiché à l'écran. J'ai donc defini mon format de base de donnees sous la forme : Clé | Valeur; une entrée par ligne du fichier. J'ai ensuite écrit mon parser d'option et les fonctions à appeler en fonction des options si la syntaxe est bonne. Là je bloque sur la fin de mon script. En fait pour ce script je ne dois utiliser que du sh et pas d'exécutable. Alors voici mon problème: Je ne peux pas ajouter les entrées en fin de fichier en faisant par exemple un echo "$key | $value" >> fichier.db, car cela ne vérifie pas l'existance de l'entrée et il y a des doublons dans les entrées de la bd; j'aimerais savoir par quelle commande interne au shell(builtin) je peux faire des check sur les lignes du fichier comme dans un tableau avant l'insertion, ceci me permettrait donc de bien gérer la commande "put" de mon sgdb(mon script). Pour la commande "del", il faut supprimer l'entrée sans produire aucun affichage, et si le nom de la clé est juste passé en argument sans sa valeur, la clé doit restée présente mais sans contenu. J'aimerais aussi dans la mesure du possible que vous m'aidiez à ce niveau. Pour le select il s'agit de recupérer l'expression passer en paramètres et lister toutes les valeurs de clés comportant des caractère de l'expression; de la même manière qu'un grep; seulement je n'ai pas droit au grep. Je ne sais pas si un "sed" ferais l'affaire.... J'aimerai aussi savoir quelle builtin appeler pour la création du fichier le cas échéant, et comment supprimer tout le contenu du fichier sans le supprimer lui même. Enfin si vous avez pu répondre à mes préoccupation et que vous disposer encore d'un peu de temps, j'aimerais savoir procéder pour stocker la base de données dans le programme lui même et non plus dans un fichier externe; de quelle manière puis-je stocker les entrées et les manipuler dans ce cas? c'est une option que je devrais pouvoir gérer, mais la priorité est aux premières questions. Merci infiniment pour votre aide précieuse. |
|
|
00
|
|
|
#2 | ||||||
|
Membre régulier
![]() Inscription : avril 2006 Messages : 103 ![]() |
Citation:
Citation:
Code :
sed -i "s#\(clef_de_recherche|\).*#\1$NEW_VAL#" tonfichierbdd.txt Citation:
Pour supprimer juste la valeur, tu reprend la commande sed de remplacement, mais tu remplace la valeur par rien du tout pour l'effacer. Citation:
Code :
sed -n '/expression/p' tonfichierbdd.txt Pour créer un fichier : Code :
Bonne chance |
||||||
|
|
00
|
|
|
#3 |
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
Bonjour,
si tu ne l'as pas encore lu, regarde Comment lire/parcourir un fichier ajoute des test, ou [ ] (c'est pareil) redirige tout vers un fichier temporaire, puis écrase l'original (après l'avoir sauvegardé) ... ? edit: ah, tu ne peux pas utiliser cp, et mv mais tu peux stocker le contenu du fichier avec les modifications dans une variable, et, quand toutes les lignes (mais on peut s'arrêter avant) ont été lues, écrire cette variable dans le fichier tout en l'écrasant (c'est peut-être plus facile ainsi) |
|
|
10
|
|
|
#4 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Merci infiniment pour vos reponses!
Et justement il est possible d'utiliser des commandes certaines commandes externes, donc merci pour vos reponses. Par contre j'ai utilise getopts pour gerer mes options, ce qui est proscrit pour le projet. Auriez vous une alternative a me proposer pour gerer mes options courtes et longues (--)? Et aussi pour awk, ca fait partie des outils a ne pas utiliser. Merci encore pour collaboration |
|
|
00
|
|
|
#5 | |||
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
Citation:
Code :
|
|||
|
|
10
|
|
|
#6 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Ouais je vois!
J'ai recuperer toute la ligne dans un tableau avant le parsing d'ailleur , du coup je fais tout a la main. merci; je reviens si j'ai un souci. Merci encore. |
|
|
00
|
|
|
#7 |
|
Membre régulier
![]() Inscription : avril 2006 Messages : 103 ![]() |
Pour remplacer le grep, tu as la commande sed au dessus qui te donne les ligne matchant ton expression.
Si tu n'a pas droit à awk pour récupérer la partie à droite du caractère "|", tu peux utiliser |
|
|
00
|
|
|
#8 | ||
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Salut les gars;
Merci vraiment pour votre aide. Je suis pas très loin d'avoir complètement terminé mon projet. Mais j'ai quelques petits souci surement de syntaxe, puisque le script est teste sur sh(mais en fait c'est interprété en bash derrière). En fait la substitution ne marche pas bien avec l'utilisation du sed comme indique par apesle. C'est a dire, quand je fais un sed -i "s#\($KEY|\).*#\1$VALUE#" $db_file (ou db_file est la variable contenant mon nom de fichier; VALUE est la variable contenant la valeur qui doit remplacer la valeur de la clé) alors, l'entrée est bien écrasée mais elle garde sa valeur, c'est dire la ligne du fichier ne change pas. Du coup cela a un impact sur la suppression quand j'essaye de supprimer juste la valeur sans supprimer la clé. Donc quand je fais un sed -i "s#\($KEY|\).*#\1#" $db_file, ca ne marche pas, car la clé reste avec sa valeur. Aussi j'ai un petit souci pour gérer les argument passe sous forme de variable(avec un "$" devant). Ceci indique que si on a '$ke1' en argument, la valeur de l'argument sera égale au contenu de la clé. Par exemple dans si dans mon fichier sh.db j'ai au moment de l'exécution de la commande (avec "=" comme séparateur dans ce cas): si on fait un ./bdsh.sh put '$clef1' '$clef2' On doit avoir dans le fichier aura dans ton sh.db Code :
Merci infiniment pour votre aide! |
||
|
|
00
|
|
|
#9 | ||||
|
Membre régulier
![]() Inscription : avril 2006 Messages : 103 ![]() |
Bonsoir,
Excuse moi, mais ton message n'est pas très clair. J'ai compris que tu n'arrive pas à changer la valeur d'une clef avec le sed. Pourtant la commande sed marche chez moi : Code :
Code :
|
||||
|
|
00
|
|
|
#10 |
|
Membre régulier
![]() Inscription : avril 2006 Messages : 103 ![]() |
Il faut que tu regarde si tes arguments commencent avec un dollar. Si c'est le cas, tu l’enlève de la chaîne et tu remplace tes arguments par leur clef respective !
|
|
|
00
|
|
|
#11 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Oui Je m'excuse le pb se trouvait au niveau du formatage de ma bd.
En fait moi je mettais un espace entre la clef, le | et la valeur c a d : $KEY | $VALUE; Du coup rien ne se passe et rien n'est afficher comme erreur. j'ai modifie le format en enlevant les espace et ca passe sans pb maintenant. Alors tu aurais une facon pratique a me proposer pour gerer le cas ou l'argument de la clef vaut le nom d'une clef (avec un "$" devant comme j'ai explique dans l'exemple de mon poste precedent? Merci encore. |
|
|
00
|
|
|
#12 | |
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
Citation:
|
|
|
|
00
|
|
|
#13 | |||
|
Membre régulier
![]() Inscription : avril 2006 Messages : 103 ![]() |
Citation:
Apres, il ne te reste plus qu'a appeler ta fonction qui permet de récupérer la valeur de la clef ! Code :
|
|||
|
|
00
|
|
|
#14 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Merci!
j'ai rencontre un autre souci avec le sed dans la subtutition avec le caractere "\" Voici ce que je tente de faire: Code :
(ngonta_e@pc-NETWORKING=yes 1313)./test.sh put val5 'lol\9' mais voici l'erreur renvoyer: Code :
sed: -e expression #1, char 22: invalid reference \9 on `s' command's RHS As-tu une idee de comment gerer ce cas specifique? Merci une fois de plus. |
|
|
00
|
|
|
#15 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Excuez moi vraiment mais je reviens encore.
En fait un autre souci. En fait pour le select, je ne dois pas afficher tous les champs valeur des ligne matchant mon expression, mais juste les valeure des cles dont les noms matchent mon expression. c a d, si j'ai dans mon fichier: et que je fait un slect "val", ca doit m'afficher juste : comme c'est le cas avec ces deux techniques que j'ai utilisees: Code :
sed -n "/$EXPR/p" $db_file | cut -d "|" -f 2 Code :
grep "$EXPR" $db_file | cut -d "|" -f 2 Merci. |
|
|
00
|
|
|
#16 | |||
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
bonjour,
Code :
c'est pour ça que tu obtiens l'erreur Citation:
Il faut vérifier que tes expressions ne contiennent pas des caractères spéciaux pour sed, et les protéger avec un \ supplémentaire. J'en vois trois : le délimiteur choisi, \, &... |
|||
|
|
00
|
|
|
#17 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Merci pour ta reponse!
Du coup j'ai egalement trouve le moyen de faire les bon match sur les nom de cle avant pour substutition; j'avoue que j'ai realise a partir de vos indication, un tres gros boulot. mais a propos de la protection du sed contre les caracteres speciaux, je n'ai pas bien compris tes recoomandations. Peux-tu etre un peu plus explicite a partir de cet example de mon script? sed -i "s#\($KEY|\).*#\1$VALUE#" $db_file; Comment proteger les caracteres speciaux dans ce cas? (Il faut remplacer ce qui est a droite du "|" apres $KEY par $VALUE, sans rien afficher bien sur!) Merci infiniment une fois de plus, le projet comporte tellement de contrainte, mais en meme je les ai presque toutes couvertes deja, et ce grace a vous en plus de certains secrets du script shel qui se sont reveles a moi. Merci. |
|
|
00
|
|
|
#18 | ||
|
Expert Confirmé Sénior
![]() Inscription : février 2008 Messages : 2 070 ![]() |
utilise une autre variable, tout simplement :
Code :
et, ne mets pas le nom des variables tout en majuscules; ça évitera des conflits avec des variables d'environnements, qui porteraient le même nom, et qui elles sont toujours en majuscules. |
||
|
|
10
|
|
|
#19 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Ok!
Bien note. Et ceci protege carement tous les caracteres speciaux contenus dans la chaine, sans affecter la chaine si elle n'en contient pas? Car c'est un programme qui effectura ensuite des unitaires avec plusieurs combinaisons de commandes et d'argument possible. Merci encore! |
|
|
00
|
|
|
#20 |
|
Futur Membre du Club
![]() Inscription : juillet 2009 Messages : 89 ![]() |
Ca ne marche toujours pas; toujours la meme erreur pour la meme commande.
J'ai esayer les deux syntaxe pour sedValue que tu m'as donnees! Merci |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com