Je possède deux fichiers de taille différente ayant en commun un champ.
fichier 1:
1 48102
2 48103
3 48152
4 48156
5 48189
fichier 2:
14 jean
503 Benjamin
48102 Georges
48103 Lili
48152 Mélina
48156 Chantal
48189 Daniel
48512 Esthelle
Je souhaite réaliser un fichier final jointant ces 2 fichier le premier par le deuxième champ et le deuxième par son premier champ.
Mais essai avec join n'ont pas était concluant et il me semble que awk peut le faire donc si quelqu'un a une idée.
Merci d'avance
# join
Posté par Old Geek . Évalué à 1. Dernière modification le 21 janvier 2013 à 10:10.
Ca passe pas avec join ??
[^] # Re: join
Posté par benofdark . Évalué à 0.
plusieurs tests mais les résultats obtenu ne sont pas concluant, comme si il commencé la jointure au milieu du fichier , je pense que c'est du au fait que les fichiers sont de taille différente et qu'il y a des trous dans mon champ de jointure.
[^] # Re: join
Posté par benofdark . Évalué à 0.
j'ai testé
join -1 2 -2 1 -o 1.1 2.2 -i --nocheck-order fichier1 fichier 2
résultat :
4 Chantal
5 Daniel
[^] # Re: join
Posté par Old Geek . Évalué à 1.
avec fichier2 sous cette forme ça passe :
00014 jean
00503 Benjamin
48102 Georges
48103 Lili
48152 Mélina
48156 Chantal
48189 Daniel
48512 Esthelle
Nicolas
# Avec join un brin de fgrep et un soupçon de cut
Posté par zipe31 . Évalué à 1.
Salut,
;-)
[^] # Re: Avec join un brin de fgrep et un soupçon de cut
Posté par benofdark . Évalué à 0.
j'obtient
join: file 2 is not in sorted order
join: file 1 is not in sorted order
je ne comprend pas vraiment d'ou vient le probleme.
[^] # Re: Avec join un brin de fgrep et un soupçon de cut
Posté par benofdark . Évalué à 0.
j'ai tester en ajoutant a mon script un sort -r sur chacun de mes chier sur le champ de la jointure, mais le résultat est toujours le même .
[^] # Re: Avec join un brin de fgrep et un soupçon de cut
Posté par zipe31 . Évalué à 1.
J'ai fait avec les exemples fournis de tes fichiers ;-\
Ce qui donne :
Le contenu des fichiers :
Le résultat du "fgrep" qui sert juste à éliminer les enregistrements de "f2" qui ne sont pas présents dans "f1" :
Et le résultat final :
$
Si ça ne marche pas chez toi, il faut chercher ailleurs… système ? shell ? format des fichiers ? etc.
[^] # Re: Avec join un brin de fgrep et un soupçon de cut
Posté par benofdark . Évalué à 1.
après quelque adaptation j'ai réussi a faire fonctionner ta solution merci beaucoup. il me reste 2 ou 3 problèmes a résoudre mais je devrai m'en sortir.
# Bizarre bizarre
Posté par benofdark . Évalué à 1.
Le truc un eu bizarre c'est que j'ai fait plusieurs jointures avec ta solution cependant une me résiste
file 1:
1 12:15:a5:45
2 17:15:a5:d5
3 12:ab:a5:a5
41 00:15:25:a5
42 18:14:a5:75
file 2
1 eth1
2 eth10
3 eth5
4 eth6
5 eth22
…
40 eth8
41 eth17
42 eth9
43 eth11
une fois de plus il me dit que file 1 n'est pas trié, est ce a cause des trou ?
[^] # Re: Bizarre bizarre
Posté par zipe31 . Évalué à 1.
Non ce n'est pas à cause des trous, mais des motifs (chiffres) et du fait que "fgrep" ne peut utiliser de regex.
On ne peut pas dire à "fgrep" de ne tenir compte que des motifs présents en début de ligne :
Comme on pourrait le faire avec "grep" ou "egrep" :
[^] # Re: Bizarre bizarre
Posté par benofdark . Évalué à 1.
je ne peut donc pas faire de jointure comme précédemment ?
[^] # Re: Bizarre bizarre
Posté par zipe31 . Évalué à 0.
Ben non ;-(
[^] # Re: Bizarre bizarre
Posté par benofdark . Évalué à 0.
Une idée, une solution je regarde du coté de awk et des tableaux là !
[^] # Re: Bizarre bizarre
Posté par Christophe Bliard . Évalué à 0.
Non, mais on peut lui dire de ne sélectionner que des mots entiers avec
-w
[^] # Re: Bizarre bizarre
Posté par zipe31 . Évalué à 0.
Exact, merci ;-)
Honte à moi en plus je m'en suis servi dernièrement ;-(
[^] # Re: Bizarre bizarre
Posté par netsurfeur . Évalué à 2.
join ne fonctionne pas parce que dans tes deux cas fichier2 est trié numériquement alors que join utilise un ordre alphabétique (40 > 5 en ordre numérique mais "40" < "5" en ordre alphabétique).
Pour ton exemple initial, la commande suivante fonctionne:
Et pour l'exemple avec les interfaces réseau:
[^] # Re: Bizarre bizarre
Posté par benofdark . Évalué à 0.
serait il possible dans mes fichiers de remplacer dans le premier champ les 1,2,3,4,5,6,7,8,9 par 01,02,03,04,05,06,07,08,09?
# Avec Zsh
Posté par calandoa . Évalué à 3.
On déclare deux tableaux associatifs (on accède aux éléments par une clé plutôt que par un indice), puis on parcourt le premier fichier et on ajoute le dernier élément :
Ce qui nous donne :
On peut aussi parcourir le second fichier et remplacer les éléments manquants par « ? » :
Ce qui nous donne :
# Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Pour le moment mon scripts ressemble à ça il sert a récupéré en SNMP les info d'un switch et à établir un tableau sous la forme :
Adresse mac port ip du switch
Mais la jointure me pose toujours problème.
Mon scripts n'est pas très beau mais c'est plutôt nouveau tout ça pour moi .
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par netsurfeur . Évalué à 3.
On peut simplifier.
Les boucles du style:
se simplifient en:
La récupération des mac peut se réécrire en remplaçant les fichiers intermédiaires par des pipes:
Comme en plus, il faut avoir des listes triées par ordre alphabétique pour join, j'y ajouterais un sort:
En faisant la même chose pour les fichiers bridge.dat et port.dat, les jointures peuvent se simplifier en:
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 1.
Merci beaucoup pour ces simplifications j'avoue que c'est beaucoup plus lisible.
je vais tester quelque truc que j'ai trouvé en fin de journée hier et je vous donnerai l'avancement .
Merci pour tout ce temps que vous me consacré.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 1.
Ma dernière jointure est toujours impossible , je cherche activement une solution.
Voici le contenu des 2 fichiers a jointer au cas ou vous auriez une idée.
et le deuxieme :
Merci d'avance
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par Christophe Bliard . Évalué à 0.
Voilà !
[^] # ça marche
Posté par benofdark . Évalué à 1.
vous êtes vraiment énorme , votre aide est précieuse et me redonne envie de me mettre sérieusement au bash.
ça doit vous semblez anodin mais j'ai beaucoup appris je vous remercie.
Je vais maintenant essayer de dynamiser encore plus le scripts en faisant appelle a un fichier contenant toute les adresse de switch .
merci encore une grosse partie recherche et réflexion m'attend je reviendrai vers vous en cas de problème.
cordialement benofdark.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par netsurfeur . Évalué à 3.
Il y avait une erreur dans mon message précédent: les fichiers doivent être triés par ordre alphabétique mais uniquement sur le champ utilisé pour la jointure. Pour être sûr que le tri se fait uniquement sur ce champ et non sur toute la ligne, il faut utiliser l'option -k de sort.
Il y a une erreur dans ton script: portname.sort n'est pas trié alphabétiquement contrairement à ce que son nom laisse supposer; port.dat non plus.
De plus, lorsque les fichiers sont correctement triés, il est inutile de bidouiller avec des cut/fgrep pour la jointure.
Enfin, il est inutile d'utiliser ./ devant le nom d'un fichier. Un nom de fichier qui n'est pas précédé d'un chemin est forcément dans le répertoire courant.
Avec tes fichiers portname.sort et mac.sort correctement triés:
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Une autre question qui me passé par la tête.
Et-il possible d'effectuer un contrôle de saisie basée sur un format (exemple MAC ou IPv4)?
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Une nouvelle question sur le même exemple de script, je me demandé si dans le fichier résulté il était possible de supprimer les ligne ayant un champ commun (exemple adresse mac) en respectant leur ordre d'arrivé dans le fichier.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Une nouvelle question sur le même exemple de script, je me demandé si dans le fichier résulté il était possible de supprimer les ligne ayant un champ commun (exemple adresse mac) en respectant leur ordre d'arrivé dans le fichier.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par Christophe Bliard . Évalué à 0.
Oui avec la commande uniq : ça garde l. J'ai un peu adapté le fichier mac.sort pour l'exemple.
--skip-fields
(ou-f
) permet d'ignorer le premier champ. Il faut alors que le reste soit identique pour que uniq puisse fonctionner. Si dans le fichier de résultat il y a des adresses mac identiques mais avec des descriptifs différents, il faut combiner plusieurs commandesPrenons le fichier suivant
On sélectionne les deux premiers champs, on lance le
uniq
et on s'en sert pour retrouver la ligne complète avecfgrep
Seule la première occurrence est conservée
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
le problème vient justement du fait que seul la dernière occurrence (j'aurai du l'annoncer plus haut ). Si le script est lancé de maniéré régulière pour garder l'information à jour en vue d'un réseau mouvent, je doit être en mesure de gardé pour 2 MAC identique la dernière occurrence remonté.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Le réel problème vient de là et j'y travail . aoprès deux precolte le fichier BD.dat m'affiche
Il faut que j'arrive a géré les doublons sur le 3eme champ en gardant le plus vieux
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
erreur de ma part c'est sur le 2 eme champs.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par Christophe Bliard . Évalué à 0.
tac
(cat
à l'envers) permet d'afficher les lignes dans l'ordre inverse, ça me permet de contourner le fait queuniq
garde la première ligneAvec deux
tac
et un peu deawk
au lieu deuniq
, on peut supprimer les doublons.Il y a peut-être une solution plus élégante et si quelqu'un est motivé, ça m'intéresse de la connaître.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par zipe31 . Évalué à 1.
La commande "uniq" a aussi une option "-w" ;-)))
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par Christophe Bliard . Évalué à 0.
Merci ! J'avais pourtant regardé dans le man pour trouver une astuce mais je n'avais pas bien cherché.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par Christophe Bliard . Évalué à 1.
Juste pour m'aider à apprendre
awk
, voici une solution sanstac
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Merci beaucoup pour vos solution.
[^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre
Posté par benofdark . Évalué à 0.
Une nouvelle question sur le même exemple de script, je me demandé si dans le fichier résulté il était possible de supprimer les ligne ayant un champ commun (exemple adresse mac) en respectant leur ordre d'arrivé dans le fichier.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.