Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/12/2011, 16h32   #1
Futur Membre du Club
 
Inscription : août 2006
Messages : 31
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 31
Points : 19
Points : 19
Par défaut [SHELL]Question délicate sur une boucle

Bonjour à tous!

Ma question est la suivante: je dois exécuter une commande sqlplus en "boucle" pour appeler une procédure stockée avec deux params issus d'un fichier csv.

Le résultat auquel j'arrive est le suivant:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
ORACLE_SID=MYBASE;
export ORACLE_SID;
 
for enreg in `cat $MYTMPPATH/$MYFILETOPARSE`
do
    OLDVAL=`echo $enreg | awk -F";" '{ print $1 }'`;
    NEWVAL=`echo $enreg | awk -F";" '{ print $2 }'`;
    OLDVAL="'"$OLDVAL"'"
    NEWVAL="'"$NEWVAL"'"
    $ORACLE_HOME/bin/sqlplus -L monID/MonMDP >> $MYFILELOG
    set serveroutput on;
    whenever sqlerror exit 1 rollback;
    whenever oserror exit 1 rollback;
    exec P2300_integ_csv(${OLDVAL},${NEWVAL});
    commit;
    exit;
done
Globalement:
1) Je ne suis pas très "satisfait", parce qu'il y a un souci sur le "exit" (qui permet de quitter le sqlplus), mais qui quitte l'exécution.
2) Je pense que je devrais sortir l'exécution de sqlplus du "do" pour l'ouvrir une fois pour toute... Mais je n'y parviens pas.
3) Mon PLUS GROS souci, c'est qu'au final, le script ne fonctionne pas sur le exec. JE ne vois pas du tout pourquoi.

sinon, pour les commandes awk, ça je suis certain que ça fonctionne, puisque j'ai testé sans la partie SQL, et j'ai affiché le contenu de mes variables OLDVAL et NEWVAL sans souci.

Si quelqu'un a une solution ou des indices à me filer... je suis preneur.

Sinon, j'ai un autre souci débile: j'ai un log dans lequel je veux piocher des lignes comme suit:
[plein de txt variable en lg][texte à lg variable à récup]
Schématiquement, je dois donc prendre toute la partie droite d'une ligne, à partir d'un point de texte identifié. Typiquement, ça donnerait un truc
[citation]SQL>Test valeur toto Erreur: donnée non conforme[/citation]
et je veux exporter uniquement
[citation]Erreur: donnée non conforme[/citation]
j'utilise, en test, ceci:
Code :
awk '/UPDATE/ {print $5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18}' $MYFILELOG > $MYPATH/$MYFILEROLLBACK
C'est crade, mais pour les tests ça fonctionne.
Quelqu'un a aussi une solution sur cet aspect?

En tout cas, toute proposition est bienvenue
magellan94 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2011, 17h58   #2
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 055
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
Localisation : France, Oise (Picardie)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : février 2006
Messages : 3 055
Points : 4 934
Points : 4 934
Citation:
Envoyé par magellan94 Voir le message
Code bash :
1
2
3
4
5
6
7
8
 
    $ORACLE_HOME/bin/sqlplus -L monID/MonMDP >> $MYFILELOG
    set serveroutput on;
    whenever sqlerror exit 1 rollback;
    whenever oserror exit 1 rollback;
    exec P2300_integ_csv(${OLDVAL},${NEWVAL});
    commit;
    exit;
Globalement:
1) Je ne suis pas très "satisfait", parce qu'il y a un souci sur le "exit" (qui permet de quitter le sqlplus), mais qui quitte l'exécution.
Salut
Effectivement, tout ce qui est entre le "$ORACLE" et le "exit" est (probablement) des commandes qui doivent être traitées par sqlplus. Mais comme tu n'as pas utilisé la bonne syntaxe pour cela, elles sont traitées par le shell.

Lorsque tu veux faire assimiler tout un code par une commande X dans ton shell, tu as 2 possibilités
1) echo "tout le code" | commandeX
Ce qui donnerait dans ton cas
Code bash :
1
2
3
4
5
6
7
8
(
    echo "set serveroutput on;"
    echo "whenever sqlerror exit 1 rollback;"
    echo "whenever oserror exit 1 rollback;"
    echo "exec P2300_integ_csv(${OLDVAL},${NEWVAL});"
    echo "commit;"
    echo "exit;"
) | $ORACLE_HOME/bin/sqlplus -L monID/MonMDP >> $MYFILELOG
Tu remarques les parenthèses (...) permettant de faire un "groupe de commandes" et d'envoyer tout le groupe dans le pipe...

2) lancer la commande avec double redirection entrée "<<" plus un flag (moi j'utilise "_EOT_" comme "End Of Text") indiquant au shell où s'arrêter
A ce moment là, tout ce qui se trouve après la commande sera considéré comme entrée standard de la commande. Et lorsque le shell arrive au flag (qui doit être seul mot de la ligne), il termine alors de traiter les lignes comme data pour la commande et reprend son fonctionnement normal

Dans ton cas, ce serait
Code bash :
1
2
3
4
5
6
7
8
$ORACLE_HOME/bin/sqlplus -L monID/MonMDP << _EOT_  >> $MYFILELOG
set serveroutput on;
whenever sqlerror exit 1 rollback;
whenever oserror exit 1 rollback;
exec P2300_integ_csv(${OLDVAL},${NEWVAL});
commit;
exit;
_EOT_

Accessoirement, je ne suis pas certain que l'ordre "exit" soit nécessaire. Il est sûrement nécessaire dans sqlplus quand tu le lances en interactif (pour quitter sqlplus) mais lancé en mode automatique, il doit probablement quitter tout seul quand il n'a plus rien à avaler (en tout cas c'est comme ça pour les commandes mysql et psql)

Citation:
Envoyé par magellan94 Voir le message
3) Mon PLUS GROS souci, c'est qu'au final, le script ne fonctionne pas sur le exec. JE ne vois pas du tout pourquoi.
Là je ne vois pas trop ce qui devrait se passer...

Citation:
Envoyé par magellan94 Voir le message
Code bash :
1
2
OLDVAL="'"$OLDVAL"'"
NEWVAL="'"$NEWVAL"'"
Pourquoi déquotter les variables ? Les quottes doubles savent gérer une variable
Code bash :
1
2
OLDVAL="'$OLDVAL'"
NEWVAL="'$NEWVAL'"

Citation:
Envoyé par magellan94 Voir le message
Sinon, j'ai un autre souci débile: j'ai un log dans lequel je veux piocher des lignes comme suit:
[plein de txt variable en lg][texte à lg variable à récup]
Schématiquement, je dois donc prendre toute la partie droite d'une ligne, à partir d'un point de texte identifié. Typiquement, ça donnerait un truc
Code :
SQL>Test valeur toto Erreur: donnée non conforme
et je veux exporter uniquement
Code :
Erreur: donnée non conforme
Code bash :
echo "ta ligne" |sed -e "s/^.\{1,\}Erreur/Erreur/g"

Citation:
Envoyé par magellan94 Voir le message
Code bash :
awk '/UPDATE/ {print $5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18}' $MYFILELOG > $MYPATH/$MYFILEROLLBACK
Code bash :
awk '/UPDATE/ {for (i=5; i <= 18; i++) printf("%s ", $i); print}' $MYFILELOG > $MYPATH/$MYFILEROLLBACK
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 30/12/2011, 18h08   #3
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 072
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 072
Points : 4 155
Points : 4 155
Bonjour,

sans oublier : comment parser un fichier

Citation:
j'ai un autre souci
normalement, autre souci = autre sujet
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 30/12/2011, 18h19   #4
Futur Membre du Club
 
Inscription : août 2006
Messages : 31
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 31
Points : 19
Points : 19
Impeccable!

Etant novice sur le shell script, je découvre donc au fur et à mesure.

Pour le coup des "echo", je comprends mieux le pourquoi. A partir de là, je vais peut-être optimiser, mais pour le moment c'est NICKEL!

Merci encore.

La seule chose que j'ai du mal à saisir, c'est la commande sed, mais je dois lire la doc pour en comprendre les subtilités concernant sa syntaxe!

Encore merci, j'ai pu en valider une énorme partie en tout cas.

au plaisir!
magellan94 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2011, 22h21   #5
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 055
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
Localisation : France, Oise (Picardie)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : Aéronautique - Marine - Espace - Armement

Informations forums :
Inscription : février 2006
Messages : 3 055
Points : 4 934
Points : 4 934
Citation:
Envoyé par magellan94 Voir le message
Pour le coup des "echo", je comprends mieux le pourquoi. A partir de là, je vais peut-être optimiser, mais pour le moment c'est NICKEL!
Quand il y en a beaucoup ça peut être chiant. Dans un cas comme le tien, moi j'aurais utilisé la solution n° 2...

Citation:
Envoyé par magellan94 Voir le message
La seule chose que j'ai du mal à saisir, c'est la commande sed, mais je dois lire la doc pour en comprendre les subtilités concernant sa syntaxe!
Bah, suffit de demander.
sed (Stream EDitor) est un éditeur de flux. Il est basé sur "ed" (le tout premier éditeur Unix sur lequel est aussi basé "vi") dont il reprend les possibilités et fonctions mais au lieu d'éditer un fichier, il édite un flot de datas (flot arrivant ici par l'intermédiaire du echo) et renvoie ensuite (comme toute commande) les infos à l'écran (infos que tu peux alors capturer, comme tu le fais déjà dans tes commandes awk, avec les backquottes => var=`echo ... |sed ...`)

Donc j'utilise sed pour modifier en live ta ligne de log. L'idée est de traiter un flot X selon ses caractéristiques générales pour avoir en sortie une data Y. Et la caractéristique que j'utilise est le mot clef "Erreur" (c'est pas super rigoureux parce que si le mot se trouve plusieurs fois sur la ligne ça va merdouiller mais j'ai pas trouvé mieux).
Je demande donc à sed d'effectuer un remplacement d'une chaine X par une chaine Y (s/chaineX/chaineY/). La chaine X sera composée de tout caractère (.) en partant du début de ligne (^) répété 1 ou plusieurs fois ({1,}) suivi de la chaine "Erreur". La chaine Y sera simplement "Erreur". Bref ça supprime simplement tout ce qu'il y a avant "Erreur" sur la ligne. Le "g" final est d'ailleurs de trop (je l'ai tapé par réflexe car il signifie "répéter l'action si la chaine X se trouve plusieurs fois sur la ligne" ce qui ne se peut pas ici).

Et la syntaxe exprimée pour représenter la chaine X cherchée n'est pas spécifiquement liée à sed mais aux expressions régulières (regex). Il s'agit d'une grammaire connue de beaucoup d'outils Unix permettant de spécifier un motif cherché selon diverses caractéristiques qui peuvent aller très loin dans la complexité (il existe des bouquins spécialisés sur les regex)
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/12/2011, 21h03   #6
Futur Membre du Club
 
Inscription : août 2006
Messages : 31
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 31
Points : 19
Points : 19
Merci pour toutes ces précisions. Cela confirme ce que je pensais dès le départ,à savoir qu'il me manque surtout des notions sur le comportement de l'exécution des scripts... De là, je crois qu'il me faudra m'envoyer un paquet de documentations histoire de bien tout saisir.

En tout cas, tout ce que tu m'as déjà précisé est copié/collé dans un coin de ma doc perso, et je vais probablement en placer une partie dans un wiki pro où je bosse (hé oui: ça aide de trouver des gens compétents)

magellan94 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h37.


 
 
 
 
Partenaires

Hébergement Web