trap, diff, goto, awk... y en a pour tout le monde
7 réponses
fredatwork
Bonjour,
j'essaie d'écrire un shell (ksh) comparant ligne à ligne 2 énormes fichiers,
j'utilise bdiff (comme diff mais pour les gros fichiers, bon choix ?)
quand les fichiers sont différents on souhaite lister les différences dans
un fichier mais
seulement les 5 premières (si il y en a un peu plus ce n'est pas trop grave)
mais on veut absolument éviter de produire un 3e énorme fichier, donc il
faut stopper
la comparaison et l'écriture du fichier.
Quand les fichiers sont identiques, on va jusqu'au bout.
J'ai donc pensé à lancer le bdiff en arrière plan,
bdiff fic1 fic2 > fic_sortie &
puis à le tuer quand il a écrit suffisamment de lignes dans le fichier de
sortie
ou attendre qu'il se termine si les fichiers en entrée sont identiques
Pour voir ou il en est dans l'écriture du fichier je fais un truc du genre :
Au passage, ca me fait mal de devoir sortir awk juste pour connaitre la
taille d'un fichier, ceci-dit
j'ai bien réfléchi et je ne vois pas de moyen plus simple, les ls | cut sont
exclus puisqu'il n'y a pas de formattage
en colonne de ls et que le format d'une ligne n'est pas fixe... si vous avez
d'autres idées je suis à l'écoute.
Ensuite, connaissant approximativement la taille d'une ligne issue du diff,
j'en déduis le nombre de lignes produites
par le diff, ce qui permet de majorer le nombre de différences produites
J'ai donc la boucle suivante :
while [ $nbligne -lt ${nb_max_lignes} ]
do
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
nbligne="taille_FIC_OUT/taille_ligne"
done
Je ne compte pas les lignes directement avec wc -l pour laisser l'accès au
fichier de sortie
uniquement au bdiff qui a déjà pas mal de boulot, qu'en pensez-vous ?
En meme temps, je dois surveiller que bdiff est toujours vivant, des fois
que les fichiers en entrée soient identiques...
Donc j'ai fait (ne vous moquez pas) :
TermineScript()
{
echo "bdiff est termine"
exit 0
}
et je lance une première fois la fonction LanceSleep en début de script
après le bdiff
Et là j'ai un problème, parce que de temps en temps j'ai un plantage à la
ligne :
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
L'erreur est " : is not an identifier"
Serait-ce mon trap qui casse mon pipe ?
Comment y remédier ?
Je ne vois pas de moyen d'éviter le pipe
Je ne connais pas de moyen d'empêcher le trap de se produire sur cette ligne
du code
Est-ce que le goto existe en ksh ? comment s'en sert-on ?
J'ai essayé (toujours interdit de rigoler) de faire un truc du genre :
while [ $nbligne -lt ${nb_max_lignes} ]
do
label:
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
nbligne="taille_FIC_OUT/taille_ligne"
done
en espérant qu'à la fin du trap on recommence au début du while et que awk
n'essaie pas de lire le pipe cassé (meme si en fait je ne suis meme pas sur
que le
problème vienne du pipe) mais mon goto ne marche pas.
Que pensez-vous de l'approche générale ?
Bon, ca fait déjà pas mal de questions et je remercie
ceux qui ont lu tout ca jusqu'au bout.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Laurent Wacrenier
fredatwork écrit:
j'essaie d'écrire un shell (ksh) comparant ligne à ligne 2 énormes fichiers, j'utilise bdiff (comme diff mais pour les gros fichiers, bon choix ?)
Sait pas. bdiff est non standart.
quand les fichiers sont différents on souhaite lister les différences dans un fichier mais seulement les 5 premières (si il y en a un peu plus ce n'est pas trop grave) mais on veut absolument éviter de produire un 3e énorme fichier, donc il faut stopper la comparaison et l'écriture du fichier. Quand les fichiers sont identiques, on va jusqu'au bout.
J'ai donc pensé à lancer le bdiff en arrière plan,
bdiff fic1 fic2 > fic_sortie &
Si seulles les 5 premières lignes sont interessantes,
bdiff fic1 fic2 | head -n 5 > fic_sortie
l'utilitaire devrait s'arreter quand il ne pourra plus écrire (quand head sera terminé ayant lu 5 lignes)
fredatwork <fredatwork@hotmail.com> écrit:
j'essaie d'écrire un shell (ksh) comparant ligne à ligne 2 énormes fichiers,
j'utilise bdiff (comme diff mais pour les gros fichiers, bon choix ?)
Sait pas. bdiff est non standart.
quand les fichiers sont différents on souhaite lister les différences dans
un fichier mais
seulement les 5 premières (si il y en a un peu plus ce n'est pas trop grave)
mais on veut absolument éviter de produire un 3e énorme fichier, donc il
faut stopper
la comparaison et l'écriture du fichier.
Quand les fichiers sont identiques, on va jusqu'au bout.
J'ai donc pensé à lancer le bdiff en arrière plan,
bdiff fic1 fic2 > fic_sortie &
Si seulles les 5 premières lignes sont interessantes,
bdiff fic1 fic2 | head -n 5 > fic_sortie
l'utilitaire devrait s'arreter quand il ne pourra plus écrire
(quand head sera terminé ayant lu 5 lignes)
j'essaie d'écrire un shell (ksh) comparant ligne à ligne 2 énormes fichiers, j'utilise bdiff (comme diff mais pour les gros fichiers, bon choix ?)
Sait pas. bdiff est non standart.
quand les fichiers sont différents on souhaite lister les différences dans un fichier mais seulement les 5 premières (si il y en a un peu plus ce n'est pas trop grave) mais on veut absolument éviter de produire un 3e énorme fichier, donc il faut stopper la comparaison et l'écriture du fichier. Quand les fichiers sont identiques, on va jusqu'au bout.
J'ai donc pensé à lancer le bdiff en arrière plan,
bdiff fic1 fic2 > fic_sortie &
Si seulles les 5 premières lignes sont interessantes,
bdiff fic1 fic2 | head -n 5 > fic_sortie
l'utilitaire devrait s'arreter quand il ne pourra plus écrire (quand head sera terminé ayant lu 5 lignes)
fredatwork
"Laurent Wacrenier" <lwa@ teaser . fr> a écrit dans le message news:
Si seulles les 5 premières lignes sont interessantes,
bdiff fic1 fic2 | head -n 5 > fic_sortie
l'utilitaire devrait s'arreter quand il ne pourra plus écrire (quand head sera terminé ayant lu 5 lignes)
Effectivement, eh ben quand je vois tout ce que j'avais fait alors que la solution tient en une ligne... Merci bien.
Toutefois si quelqu'un a des réponses aux autres questions incluses dans mon mail d'origine
"Laurent Wacrenier" <lwa@ teaser . fr> a écrit dans le message news:
slrncl0uja.3si.lwa@victor.teaser.fr...
Si seulles les 5 premières lignes sont interessantes,
bdiff fic1 fic2 | head -n 5 > fic_sortie
l'utilitaire devrait s'arreter quand il ne pourra plus écrire
(quand head sera terminé ayant lu 5 lignes)
Effectivement, eh ben quand je vois tout ce que j'avais fait
alors que la solution tient en une ligne...
Merci bien.
Toutefois si quelqu'un a des réponses aux autres questions
incluses dans mon mail d'origine
Au passage, ca me fait mal de devoir sortir awk juste pour connaitre la taille d'un fichier, ceci-dit j'ai bien réfléchi et je ne vois pas de moyen plus simple, les ls | cut sont exclus puisqu'il n'y a pas de formattage en colonne de ls et que le format d'une ligne n'est pas fixe... si vous avez d'autres idées je suis à l'écoute.
L'output dans ls -s n'est pas la taille du fichier mais son occupation disque (comme dans du). C'est ls -l pour avoir la taille.
t'as le "tr -s ' '" qui permet d'utiliser "cut -d' ' -f"
Sinon, tu as zsh, GNU stat, GNU find, perl... pour trouver la taille d'un fichier.
T'as:
wc -c < fichier
(mais sur certains systemes, ca va lire "fichier" dans son integralité).
Ensuite, connaissant approximativement la taille d'une ligne issue du diff, j'en déduis le nombre de lignes produites
Au passage, ca me fait mal de devoir sortir awk juste pour connaitre la
taille d'un fichier, ceci-dit
j'ai bien réfléchi et je ne vois pas de moyen plus simple, les ls | cut sont
exclus puisqu'il n'y a pas de formattage
en colonne de ls et que le format d'une ligne n'est pas fixe... si vous avez
d'autres idées je suis à l'écoute.
L'output dans ls -s n'est pas la taille du fichier mais son
occupation disque (comme dans du). C'est ls -l pour avoir la
taille.
t'as le "tr -s ' '" qui permet d'utiliser "cut -d' ' -f"
Sinon, tu as zsh, GNU stat, GNU find, perl... pour trouver la
taille d'un fichier.
T'as:
wc -c < fichier
(mais sur certains systemes, ca va lire "fichier" dans son
integralité).
Ensuite, connaissant approximativement la taille d'une ligne issue du diff,
j'en déduis le nombre de lignes produites
Au passage, ca me fait mal de devoir sortir awk juste pour connaitre la taille d'un fichier, ceci-dit j'ai bien réfléchi et je ne vois pas de moyen plus simple, les ls | cut sont exclus puisqu'il n'y a pas de formattage en colonne de ls et que le format d'une ligne n'est pas fixe... si vous avez d'autres idées je suis à l'écoute.
L'output dans ls -s n'est pas la taille du fichier mais son occupation disque (comme dans du). C'est ls -l pour avoir la taille.
t'as le "tr -s ' '" qui permet d'utiliser "cut -d' ' -f"
Sinon, tu as zsh, GNU stat, GNU find, perl... pour trouver la taille d'un fichier.
T'as:
wc -c < fichier
(mais sur certains systemes, ca va lire "fichier" dans son integralité).
Ensuite, connaissant approximativement la taille d'une ligne issue du diff, j'en déduis le nombre de lignes produites
Je lance tout ce bazar en arrière plan comme si c'était un SCRIPT shell L'idée est de commencer par attendre un certain temps, envoyer un signal à mon diff pour voir si il tourne toujours, si il est mort j'envoie USR1 au programme principal ($$) qui se termine alors si il est toujours en vie j'envoie USR2 qui relance cette commande.
[...]
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` L'erreur est " : is not an identifier" Serait-ce mon trap qui casse mon pipe ?
Je ne sais pas mais ceci est une erreur de ksh reportee par exemple par read
$ ksh -c 'read ""' ksh: : is not an identifier
Comment y remédier ?
Regarder la ou il peut y avoir une commande attandant le nom d'une variable qui recoit un truc invalide.
eh bien je pense que le programme principal reçoit un signal pendant
l'instruction taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` plus précisément après le ls et avant le awk. ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est terminée il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire sur la sortie standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ? Si oui comment éviter ça ?
[...]
Est-ce que le goto existe en ksh ? comment s'en sert-on ?
Non, pas de goto.
ok. ni aucune autre instruction équivalente j'imagine...
Merci beaucoup de ton aide.
"Stephane Chazelas" <cette.adresse@est.invalid> a écrit dans le message
news: slrncl2kf0.ak.stephane.chazelas@spam.is.invalid...
2004-09-21, 19:22(+02), fredatwork:
[...]
j'essaie d'écrire un shell (ksh) comparant ligne à ligne 2 énormes
fichiers,
Tu essaies de reecrire ksh. Bonne idee, c'est vrai que
l'original etait pas super.
Peut-etre que tu veux plutot ecrire un script ?
Sans commentaire...
L'output dans ls -s n'est pas la taille du fichier mais son
occupation disque (comme dans du). C'est ls -l pour avoir la
taille.
Effectivement
t'as le "tr -s ' '" qui permet d'utiliser "cut -d' ' -f"
Sinon, tu as zsh, GNU stat, GNU find, perl... pour trouver la
taille d'un fichier.
Donc pas moyen d'éviter les | en ksh sauf avec wc -c
T'as:
wc -c < fichier
(mais sur certains systemes, ca va lire "fichier" dans son
integralité).
C'est apparemment le cas de mon système qui répond en plus d'une minute
sur un fichier de 800 Mo
Je lance tout ce bazar en arrière plan comme si c'était un SCRIPT shell
L'idée est de commencer par attendre un certain temps,
envoyer un signal à mon diff pour voir si il tourne toujours,
si il est mort j'envoie USR1 au programme principal ($$) qui se termine
alors
si il est toujours en vie j'envoie USR2 qui relance cette commande.
[...]
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
L'erreur est " : is not an identifier"
Serait-ce mon trap qui casse mon pipe ?
Je ne sais pas mais ceci est une erreur de ksh reportee par
exemple par read
$ ksh -c 'read ""'
ksh: : is not an identifier
Comment y remédier ?
Regarder la ou il peut y avoir une commande attandant le nom
d'une variable qui recoit un truc invalide.
eh bien je pense que le programme principal reçoit un signal pendant
l'instruction
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
plus précisément après le ls et avant le awk.
ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est
terminée
il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire
sur la sortie
standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ?
Si oui comment éviter ça ?
[...]
Est-ce que le goto existe en ksh ? comment s'en sert-on ?
Non, pas de goto.
ok. ni aucune autre instruction équivalente j'imagine...
Je lance tout ce bazar en arrière plan comme si c'était un SCRIPT shell L'idée est de commencer par attendre un certain temps, envoyer un signal à mon diff pour voir si il tourne toujours, si il est mort j'envoie USR1 au programme principal ($$) qui se termine alors si il est toujours en vie j'envoie USR2 qui relance cette commande.
[...]
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` L'erreur est " : is not an identifier" Serait-ce mon trap qui casse mon pipe ?
Je ne sais pas mais ceci est une erreur de ksh reportee par exemple par read
$ ksh -c 'read ""' ksh: : is not an identifier
Comment y remédier ?
Regarder la ou il peut y avoir une commande attandant le nom d'une variable qui recoit un truc invalide.
eh bien je pense que le programme principal reçoit un signal pendant
l'instruction taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` plus précisément après le ls et avant le awk. ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est terminée il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire sur la sortie standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ? Si oui comment éviter ça ?
[...]
Est-ce que le goto existe en ksh ? comment s'en sert-on ?
Non, pas de goto.
ok. ni aucune autre instruction équivalente j'imagine...
Je ne sais pas pourquoi tu veux eviter des pipes, mais note que `...` cree un pipe (qui rammasse tout ce qu'ecrit le sous-shell pour en faire des arguments de commandes).
Pour lancer un sous-shell, c'est des parentheses qu'il te faut:
(sleep ...) &
[...]
eh bien je pense que le programme principal reçoit un signal pendant l'instruction taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` plus précisément après le ls et avant le awk.
Il n'y a pas de apres et avant. ls et awk sont lances en meme temps. Si le shell recoit un USR1, ls et awk aussi et le shell execute la trappe.
ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est terminée il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire sur la sortie standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ? Si oui comment éviter ça ?
Non, pas tres vraissemblable. Ce message d'erreur est un message de ksh, il est probablement generé par les commandes dans la trappe.
Mets un set -x au debut pour mieux voir ce qui se passe.
Je ne sais pas pourquoi tu veux eviter des pipes, mais note que
`...` cree un pipe (qui rammasse tout ce qu'ecrit le sous-shell
pour en faire des arguments de commandes).
Pour lancer un sous-shell, c'est des parentheses qu'il te faut:
(sleep ...) &
[...]
eh bien je pense que le programme principal reçoit un signal pendant
l'instruction
taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'`
plus précisément après le ls et avant le awk.
Il n'y a pas de apres et avant. ls et awk sont lances en meme
temps. Si le shell recoit un USR1, ls et awk aussi et le shell
execute la trappe.
ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est
terminée
il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire
sur la sortie
standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ?
Si oui comment éviter ça ?
Non, pas tres vraissemblable. Ce message d'erreur est un message
de ksh, il est probablement generé par les commandes dans la
trappe.
Mets un set -x au debut pour mieux voir ce qui se passe.
Je ne sais pas pourquoi tu veux eviter des pipes, mais note que `...` cree un pipe (qui rammasse tout ce qu'ecrit le sous-shell pour en faire des arguments de commandes).
Pour lancer un sous-shell, c'est des parentheses qu'il te faut:
(sleep ...) &
[...]
eh bien je pense que le programme principal reçoit un signal pendant l'instruction taille_FIC_OUT=`ls -s fic_sortie | awk '{print $1}'` plus précisément après le ls et avant le awk.
Il n'y a pas de apres et avant. ls et awk sont lances en meme temps. Si le shell recoit un USR1, ls et awk aussi et le shell execute la trappe.
ça le déroute dans ma fonction LanceSleep, une fois que celle-ci est terminée il revient à l'instruction ci-dessus, et je pense que le awk essaie de lire sur la sortie standard mais qu'il n'y a plus rien à y lire parce que mon pipe est cassé
Ma question est : est-ce vraisemblable ? Si oui comment éviter ça ?
Non, pas tres vraissemblable. Ce message d'erreur est un message de ksh, il est probablement generé par les commandes dans la trappe.
Mets un set -x au debut pour mieux voir ce qui se passe.
-- Stephane
fredatwork
"Stephane Chazelas" a écrit dans le message news:
Non, pas tres vraissemblable. Ce message d'erreur est un message de ksh, il est probablement generé par les commandes dans la trappe.
Mets un set -x au debut pour mieux voir ce qui se passe.
J'avais déjà fait la manoeuvre, mais peut-être sauras-tu interpréter mieux que moi :
Je lance ksh -x testdiff.ksh
ce qui donne (je te passe le début) :
Quelques centaines de fois : + [ 0 -lt 20 ] + + awk {print $1} + ls -s ficresult taille_FIC_OUT=0 + nbligne=taille_FIC_OUT/taille_ligne
Lance Sleep ./testdiff.ksh[57]: : is not an identifier
J'ai bien noté la différence entre `...` et les parenthèses J'ai effectué le remplacement. Ca n'a pas résolu le problème ci-dessus mais je sais bien que tu ne prétendais pas le contraire. Quand aux pipes, je n'ai rien contre (pas de mauvais jeux de mots) mais j'avais simplement l'impression que mon pipe était la source du problème. Des bonnes idées ?
Merci une nouvelle fois.
"Stephane Chazelas" <cette.adresse@est.invalid> a écrit dans le message
news: slrncl2qqd.ak.stephane.chazelas@spam.is.invalid...
Non, pas tres vraissemblable. Ce message d'erreur est un message
de ksh, il est probablement generé par les commandes dans la
trappe.
Mets un set -x au debut pour mieux voir ce qui se passe.
J'avais déjà fait la manoeuvre, mais peut-être sauras-tu interpréter
mieux que moi :
Je lance
ksh -x testdiff.ksh
ce qui donne (je te passe le début) :
Quelques centaines de fois :
+ [ 0 -lt 20 ]
+ + awk {print $1}
+ ls -s ficresult
taille_FIC_OUT=0
+ nbligne=taille_FIC_OUT/taille_ligne
Lance Sleep
./testdiff.ksh[57]: : is not an identifier
J'ai bien noté la différence entre `...` et les parenthèses
J'ai effectué le remplacement.
Ca n'a pas résolu le problème ci-dessus mais je sais bien que tu ne
prétendais pas le contraire.
Quand aux pipes, je n'ai rien contre (pas de mauvais jeux de mots)
mais j'avais simplement l'impression que mon pipe était la source du
problème.
Des bonnes idées ?
Lance Sleep ./testdiff.ksh[57]: : is not an identifier
J'ai bien noté la différence entre `...` et les parenthèses J'ai effectué le remplacement. Ca n'a pas résolu le problème ci-dessus mais je sais bien que tu ne prétendais pas le contraire. Quand aux pipes, je n'ai rien contre (pas de mauvais jeux de mots) mais j'avais simplement l'impression que mon pipe était la source du problème. Des bonnes idées ?