J'ai une demande assez compliquée, et je serais reconnaissant
à celui ou celle qui pourrait m'aider.
Je cherche à faire un script shell qui réalise une sorte de
'merge' entre fichiers, de la façon suivante. Soit par exemple
les cinq fichiers suivants :
Je cherche à obtenir un fichier ./resultat qui contienne dans l'ordre
toutes les lignes de /un/chemin/source, /un/autre/chemin/source et
/encore/un/chemin/source, mais en remplaçant toute ligne par celle de
./reference à partir du moment où la liste de nombres du début de la
ligne est la même. C'est-à-dire :
J'aimerais bien que ça fonctionne sur un Solaris avec bourne shell ou
korn shell, et si possible en utilisant /usr/bin/nawk (ou éventuellement
/usr/xpg4/bin/awk), mais aussi sur AIX ou sur Linux avec les awk qu'on
y trouve. Si vraiment c'est trop compliqué avec awk, il est probable
que je puisse utiliser perl, mais comme je n'en suis pas certain je
préfèrerais vraiment awk. À moins bien sûr qu'il n'existe une autre
commande miracle qui fasse le 'merge' avec quelques options bien
choisies ! (C'est un problème réel, pas un exercice scolaire pour
apprendre à utiliser awk.)
Les fichiers sources peuvent être en nombre variable, mais leurs
chemins d'accès sont tous listés dans l'ordre dans le fichier
./liste_chemins . S'il est plus simple de commencer par créer
un fichier ./sources qui contienne tous les autres, je sais faire.
Par exemple :
for src in $(cat ./liste_chemins)
do
cat $src/source
done > ./sources
... mais si on peut tout faire en une passe, c'est mieux.
Merci à qui aura eu le courage de lire jusque là, et qui saurait
me donner de bons conseils : je ne tiens pas forcément à ce qu'on
me fasse tout le boulot.
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
Olivier Miakinen
Le 12/04/2012 17:49, j'écrivais :
J'ai une demande assez compliquée, et je serais reconnaissant à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. Il faut juste que je vérifie si chaque ligne du fichier ./reference a bien son pendant dans au moins l'un des fichiers /path/source, et si ces fichiers /path/source ne peuvent que gagner des lignes (avec des numéros nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution fonctionnera même si ces contraintes ne sont pas respectées, mais sinon il est possible que j'aie une solution de repli.
Cordialement, -- Olivier Miakinen
Le 12/04/2012 17:49, j'écrivais :
J'ai une demande assez compliquée, et je serais reconnaissant
à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui
fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis
en train de me demander si je ne pourrais pas me simplifier la
vie en faisant le travail une fois à la main, suivi par un diff,
puis en utilisant la commande patch. Il faut juste que je vérifie
si chaque ligne du fichier ./reference a bien son pendant dans
au moins l'un des fichiers /path/source, et si ces fichiers
/path/source ne peuvent que gagner des lignes (avec des numéros
nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution
fonctionnera même si ces contraintes ne sont pas respectées, mais
sinon il est possible que j'aie une solution de repli.
J'ai une demande assez compliquée, et je serais reconnaissant à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. Il faut juste que je vérifie si chaque ligne du fichier ./reference a bien son pendant dans au moins l'un des fichiers /path/source, et si ces fichiers /path/source ne peuvent que gagner des lignes (avec des numéros nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution fonctionnera même si ces contraintes ne sont pas respectées, mais sinon il est possible que j'aie une solution de repli.
Cordialement, -- Olivier Miakinen
Alain Montfranc
Olivier Miakinen a utilisé son clavier pour écrire :
Le 12/04/2012 17:49, j'écrivais :
J'ai une demande assez compliquée, et je serais reconnaissant à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. Il faut juste que je vérifie si chaque ligne du fichier ./reference a bien son pendant dans au moins l'un des fichiers /path/source, et si ces fichiers /path/source ne peuvent que gagner des lignes (avec des numéros nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution fonctionnera même si ces contraintes ne sont pas respectées, mais sinon il est possible que j'aie une solution de repli.
Cordialement,
Regarde peut etre du côté de "join"
Olivier Miakinen a utilisé son clavier pour écrire :
Le 12/04/2012 17:49, j'écrivais :
J'ai une demande assez compliquée, et je serais reconnaissant
à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui
fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis
en train de me demander si je ne pourrais pas me simplifier la
vie en faisant le travail une fois à la main, suivi par un diff,
puis en utilisant la commande patch. Il faut juste que je vérifie
si chaque ligne du fichier ./reference a bien son pendant dans
au moins l'un des fichiers /path/source, et si ces fichiers
/path/source ne peuvent que gagner des lignes (avec des numéros
nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution
fonctionnera même si ces contraintes ne sont pas respectées, mais
sinon il est possible que j'aie une solution de repli.
Olivier Miakinen a utilisé son clavier pour écrire :
Le 12/04/2012 17:49, j'écrivais :
J'ai une demande assez compliquée, et je serais reconnaissant à celui ou celle qui pourrait m'aider.
[...]
À moins bien sûr qu'il n'existe une autre commande miracle qui fasse le 'merge' avec quelques options bien choisies !
[...]
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. Il faut juste que je vérifie si chaque ligne du fichier ./reference a bien son pendant dans au moins l'un des fichiers /path/source, et si ces fichiers /path/source ne peuvent que gagner des lignes (avec des numéros nouveaux). Le fichier ./references, lui, ne bougera pas.
Un programme shell + awk sera toujours préférable car la solution fonctionnera même si ces contraintes ne sont pas respectées, mais sinon il est possible que j'aie une solution de repli.
Cordialement,
Regarde peut etre du côté de "join"
Olivier Miakinen
Bonjour,
Le 12/04/2012 20:18, Alain Montfranc m'a répondu :
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. [...]
Regarde peut etre du côté de "join"
Je viens d'aller voir le man de join.
C'était une bonne idée, mais difficile à appliquer. D'une part parce que le 'champ de fusion' (join field) ne peut pas être repéré par de simples séparateurs de champs, d'autre part parce qu'il faut trier les lignes, ce que je ne veux pas faire.
Merci en tout cas, -- Olivier Miakinen
Bonjour,
Le 12/04/2012 20:18, Alain Montfranc m'a répondu :
Quoique cela m'apporte des contraintes supplémentaires, je suis
en train de me demander si je ne pourrais pas me simplifier la
vie en faisant le travail une fois à la main, suivi par un diff,
puis en utilisant la commande patch. [...]
Regarde peut etre du côté de "join"
Je viens d'aller voir le man de join.
C'était une bonne idée, mais difficile à appliquer. D'une part parce
que le 'champ de fusion' (join field) ne peut pas être repéré par
de simples séparateurs de champs, d'autre part parce qu'il faut trier
les lignes, ce que je ne veux pas faire.
Le 12/04/2012 20:18, Alain Montfranc m'a répondu :
Quoique cela m'apporte des contraintes supplémentaires, je suis en train de me demander si je ne pourrais pas me simplifier la vie en faisant le travail une fois à la main, suivi par un diff, puis en utilisant la commande patch. [...]
Regarde peut etre du côté de "join"
Je viens d'aller voir le man de join.
C'était une bonne idée, mais difficile à appliquer. D'une part parce que le 'champ de fusion' (join field) ne peut pas être repéré par de simples séparateurs de champs, d'autre part parce qu'il faut trier les lignes, ce que je ne veux pas faire.
2012-04-12 20:30:10 +0100, Stephane Chazelas: [...] > $ cat a? | awk -F'[)]' 'NR==FNR{a[$1]=$0;next}; $1 in a {$0=a[$1]};1' r - [...]
Pas besoin de cat:
awk -F'[)]' 'NR==FNR{a[$1]=$0;next}; $1 in a {$0=a[$1]};1' r a?
[...]
Ah et sous Solaris, utiliser le nawk ou /usr/xpg4/bin/awk.
Il se peut que
awk -F'[)]' ' NR == FNR {a[$1]=$0;next} $1 in a {$0=a[$1]} {print}' r a?
Avec le vieux awk de /usr/bin toutefois.
-- Stephane
Olivier Miakinen
Bonjour,
Ce que j'aime bien avec tes réponses, c'est qu'elles sont souvent comme des petites énigmes de logique : il faut comprendre comment ça marche (puisque ça marche), et quand on a compris c'est une illumination !
Ok, tu simplifies un peu les données, mais ça me va bien : la partie difficile n'était pas là.
$ cat a? | awk -F'[)]'
Tiens, c'est vrai qu'on n'a pas besoin de délimiteur de début. L'une de mes objections à la suggestion d'Alain Montfranc saute par la même occasion (mais pas la seconde).
'NR==FNR{a[$1]=$0;next};
Génial, ce test « NR==FNR » ! J'ai mis un peu de temps à le comprendre, mais il signifie tout simplement « on est dans le premier fichier » (donc dans r).
Voilà une méthode simple et de bon goût pour traiter un fichier d'une certaine façon, et tous les autres fichiers d'une autre façon. Mais je mettrai quand même un commentaire pour l'expliquer !
Quoi qu'il en soit, mon problème est résolu.
$1 in a {$0=a[$1]};
Oui, logique.
1' r -
J'ai mis quelques secondes aussi à comprendre ce « 1 » qui est équivalent à « 1 {print} » ou encore à « {print} ». Même si c'est un peu plus long à écrire, je pense que j'emploierai la dernière de ces trois méthodes : je la trouve plus lisible que la 1re.
Eh bien voilà. C'est si simple quand un Stéphane Chazelas nous donne la solution !!!
Grand merci à toi, -- Olivier Miakinen
Bonjour,
Ce que j'aime bien avec tes réponses, c'est qu'elles sont souvent
comme des petites énigmes de logique : il faut comprendre comment
ça marche (puisque ça marche), et quand on a compris c'est une
illumination !
Ok, tu simplifies un peu les données, mais ça me va bien : la partie
difficile n'était pas là.
$ cat a? | awk -F'[)]'
Tiens, c'est vrai qu'on n'a pas besoin de délimiteur de début. L'une
de mes objections à la suggestion d'Alain Montfranc saute par la même
occasion (mais pas la seconde).
'NR==FNR{a[$1]=$0;next};
Génial, ce test « NR==FNR » ! J'ai mis un peu de temps à le comprendre,
mais il signifie tout simplement « on est dans le premier fichier »
(donc dans r).
Voilà une méthode simple et de bon goût pour traiter un fichier d'une
certaine façon, et tous les autres fichiers d'une autre façon. Mais je
mettrai quand même un commentaire pour l'expliquer !
Quoi qu'il en soit, mon problème est résolu.
$1 in a {$0=a[$1]};
Oui, logique.
1' r -
J'ai mis quelques secondes aussi à comprendre ce « 1 » qui est
équivalent à « 1 {print} » ou encore à « {print} ». Même si c'est
un peu plus long à écrire, je pense que j'emploierai la dernière
de ces trois méthodes : je la trouve plus lisible que la 1re.
Ce que j'aime bien avec tes réponses, c'est qu'elles sont souvent comme des petites énigmes de logique : il faut comprendre comment ça marche (puisque ça marche), et quand on a compris c'est une illumination !
Ok, tu simplifies un peu les données, mais ça me va bien : la partie difficile n'était pas là.
$ cat a? | awk -F'[)]'
Tiens, c'est vrai qu'on n'a pas besoin de délimiteur de début. L'une de mes objections à la suggestion d'Alain Montfranc saute par la même occasion (mais pas la seconde).
'NR==FNR{a[$1]=$0;next};
Génial, ce test « NR==FNR » ! J'ai mis un peu de temps à le comprendre, mais il signifie tout simplement « on est dans le premier fichier » (donc dans r).
Voilà une méthode simple et de bon goût pour traiter un fichier d'une certaine façon, et tous les autres fichiers d'une autre façon. Mais je mettrai quand même un commentaire pour l'expliquer !
Quoi qu'il en soit, mon problème est résolu.
$1 in a {$0=a[$1]};
Oui, logique.
1' r -
J'ai mis quelques secondes aussi à comprendre ce « 1 » qui est équivalent à « 1 {print} » ou encore à « {print} ». Même si c'est un peu plus long à écrire, je pense que j'emploierai la dernière de ces trois méthodes : je la trouve plus lisible que la 1re.
Eh bien voilà. C'est si simple quand un Stéphane Chazelas nous donne la solution !!!
Grand merci à toi, -- Olivier Miakinen
Olivier Miakinen
Le 12/04/2012 21:38, Alain Ketterlin m'a répondu :
[...]
Si tu es limité à awk, tu peux regarder du coté de getline, [...]
et dans les actions associées je lirais les lignes a la mano (avec getline, donc). Ensuite, regexp et tout le tintouin, et on stocke tout dans des tableaux.
C'est bien ce que j'avais commencé à faire, mais j'avais un peu de mal à m'en sortir avant que Stéphane n'arrive avec son astuce NR==FNR.
Bref, c'est un peu dommage de devoir le faire en awk, mais a priori c'est possible.
Qu'est-ce qui n'est pas possible en awk, fût-ce au prix de contorsions incroyables... ou d'astuces géniales ? ;-)
Cordialement, -- Olivier Miakinen
Le 12/04/2012 21:38, Alain Ketterlin m'a répondu :
[...]
Si tu es limité à awk, tu peux regarder du coté de getline, [...]
et dans les actions associées je lirais les lignes a la mano (avec
getline, donc). Ensuite, regexp et tout le tintouin, et on stocke tout
dans des tableaux.
C'est bien ce que j'avais commencé à faire, mais j'avais un peu de mal
à m'en sortir avant que Stéphane n'arrive avec son astuce NR==FNR.
Bref, c'est un peu dommage de devoir le faire en awk, mais a priori
c'est possible.
Qu'est-ce qui n'est pas possible en awk, fût-ce au prix de contorsions
incroyables... ou d'astuces géniales ? ;-)
Le 12/04/2012 21:38, Alain Ketterlin m'a répondu :
[...]
Si tu es limité à awk, tu peux regarder du coté de getline, [...]
et dans les actions associées je lirais les lignes a la mano (avec getline, donc). Ensuite, regexp et tout le tintouin, et on stocke tout dans des tableaux.
C'est bien ce que j'avais commencé à faire, mais j'avais un peu de mal à m'en sortir avant que Stéphane n'arrive avec son astuce NR==FNR.
Bref, c'est un peu dommage de devoir le faire en awk, mais a priori c'est possible.
Qu'est-ce qui n'est pas possible en awk, fût-ce au prix de contorsions incroyables... ou d'astuces géniales ? ;-)
Cordialement, -- Olivier Miakinen
Olivier Miakinen
Le 12/04/2012 21:43, Stephane Chazelas se répondit :
Pas besoin de cat:
awk -F'[)]' 'NR==FNR{a[$1]=$0;next}; $1 in a {$0=a[$1]};1' r a?
Oui, en effet.
[...]
Ah et sous Solaris, utiliser le nawk ou /usr/xpg4/bin/awk.
C'est bien le cas, d'ailleurs je l'avais précisé dans mon premier article.
Il se peut que
awk -F'[)]' ' NR == FNR {a[$1]=$0;next} $1 in a {$0=a[$1]} {print}' r a?
Avec le vieux awk de /usr/bin toutefois.
Possible, mais bon, je vais laisser ce bon vieux awk dormir, ça vaut mieux.
Le 12/04/2012 21:43, Stephane Chazelas se répondit :
Pas besoin de cat:
awk -F'[)]' 'NR==FNR{a[$1]=$0;next}; $1 in a {$0=a[$1]};1' r a?
Oui, en effet.
[...]
Ah et sous Solaris, utiliser le nawk ou /usr/xpg4/bin/awk.
C'est bien le cas, d'ailleurs je l'avais précisé dans mon premier
article.
Il se peut que
awk -F'[)]' '
NR == FNR {a[$1]=$0;next}
$1 in a {$0=a[$1]}
{print}' r a?
Avec le vieux awk de /usr/bin toutefois.
Possible, mais bon, je vais laisser ce bon vieux awk dormir, ça vaut
mieux.