[BASH] joindre 2 fichiers sans Join

Fermé
marc - 5 févr. 2005 à 20:55
 no exess - 2 déc. 2007 à 21:36
Bonjour,
voici mon problème désormais

J'ai un fichier original de la forme :

1234234:toto:prenomtoto:23542345:toto@toierito.com
...
...

J'ai créé un login pour chaque ligne (en fonction du nom et du prenom) et mis tout ça dans un autre fichier de la forme :

totopre
...
...

Ce que je souhaite réaliser, c'est ajouter le login 1 à la suite de la ligne 1 du fichier original, etc pour toutes les lignes, de façon à ce que cela donne :

1234234:toto:prenomtoto:23542345:toto@toierito.com:totopre
...
...

Pour joindre 2 fichiers, il ya la commande Join mais celle ci nécessite un champ commun dans les 2 fichiers à joindre. Et malheureusement ce n'est pas le cas.
J'ai aussi trouvé avec mon ami google que la commande Cat permet de concaténer 2 fichiers mais malheureusement la joindre se fait fichier par fichier et non ligne par ligne.
De plus, le man ne me propose apparemment pas de solutions dans les options de ces commandes...

avez vous une idée ou une solution, svp?

merci d'avance

marc
A voir également:

9 réponses

M&M Messages postés 5038 Date d'inscription dimanche 11 août 2002 Statut Contributeur Dernière intervention 3 décembre 2009 667
6 févr. 2005 à 20:26
Si c'est pas trop long, c'est sûrement plus rapide de le faire à la main.


On fait cela sur le coin d'une table en lisant ligne à ligne les deux fichiers A et B et en réécrivant le regroupement ligneA + ":"+ ligneB dans un fichier C du début jusqu'à la fin. J'écrirais cela en awk ou en perl.

Si c'est toi qui a créé le fichier totopre en lisant le fichier A et en tronquant le prénom à ses trois premiers caractères, c'est encore plus simple, n'ouvre que le fichier A, extraits chaque champ en définissant le caractère ":" comme séparateur. Puis-je t eproposer de profiter de la puissance de awk ou de perl qui feront cela en un tour de main:
crée donc un fichier script.awk qui contient :
BEGIN { FS=":";OFS=":"}
//	{print $0,$2 substr($3,1,3)}
END {}
et exécute-le en lançant awk -f script.awk fichierA
Court et bon!
_ç_§:
(.)#(.)
0
Bonjour M&M

Merci pour ta reponse.
Cependant c'est un peu plus compliqué : ce sont des logins qui vont etre ajoutés automatiquement aux comptes utilisateurs avec useradd.
Je ne peux pas le faire à la main car cela doit être réutilisable!
Comme ce sont des logins, ils doivent etre uniques, donc si un autre utilisateur se nomme "toto preblabla" son login doit etre différent de celui de "toto prenomtoto"...
J'ai d'un coté le fichier A dont j'extrait le nom et les prenom, je cree un login unique (si totopre existe deja, alors le login deviendra totopr1, et ainsi de suite) et je redirige ces logins uniques vers fichier B.

Or sur fichier A, il y a aussi le nom du groupe auquel appartient l'utilisateur. Donc pour ajouter l'utilisateur avec ' useradd login groupe ' il faudrait que je puisse mettre à la fin de chaque ligne le login unique correspondant.

Concernant Awk, que je ne maitrise pas vraiment, entre le BEGIN et le END, peut on mettre plusieurs lignes de codes, de façon à ce que je calcule mon login unique à l'intérieur?

Si tu vois ce que je veux dire, crois tu cela possible?

(je resume l'idée pour bien être clair : partir du fichier A, executer le awk c'est à dire faire le BEGIN, puis appeler ma fonction qui calcule le login unique, puis ajouter ce dernier à la fin de la ligne en cours, rediriger le flot vers un fichier B, et enfin faire le END ; tout cela pour chaque ligne bien sûr)

merci d'avance de ton aide ;)
0
M&M Messages postés 5038 Date d'inscription dimanche 11 août 2002 Statut Contributeur Dernière intervention 3 décembre 2009 667
7 févr. 2005 à 02:46
Oui c'est possible, bien sûr. Tu peux lire le paramètre de la ligne de commande et ouvrir une première fois ce fichier sous la clause Begin. (Tu pourrais aussi bien y ouvrir ton fichier B).
Je t'arrange un truc sur le coin de la table, j'y recherche tous les homonymes et j'y associe un nom unique (ici, le même, suivi d'un indice numérique)
Puis sous la section des patterns, j'introduis les noms uniques quand c'est nécessaire.
BEGIN { 
  IN_FILE = ARGV[1];  #print "Ouverture de "IN_FILE"\n";
  FS=":";OFS=":"; i=0;lpre=3
  while ((getline < IN_FILE)>0) {
    #nom[i]=$2;prenom[i++]=$3
    nomplus3=$2 substr($3,1,lpre);
    #prenom_du[nomplus3]=$3;
    if (nbr_de[nomplus3]++ >0) { 
      unique[$2$3]=nomplus3 sprintf("%s",nbr_de[nomplus3]);
      print "nouveau nom = " unique[$2$3];}    
  } 
  close(IN_FILE);
  #  print "Recherche des homonymes\n------------------------";
  #  for (mec in nbr_de) {if (nbr_de[mec]>1) {
  #        printf ("%2s fois %10s\n",nbr_de[mec],mec);h++}
  #  } 
  #  print (h>1)?"\n":"Aucun.\n";
}

//  {if ($2$3 in unique) {print $0,unique[$2$3];}
     else                {print $0,$2 substr($3,1,lpre);}
    }
_ç_§:
(.)#(.)
0
Chapeau bas M&M pour ces scripts.
Dans le même ordre d'idée, vois tu un moyen de joindre/grouper N lines sur 1 dans un fichier ayant la meme occurence ?

line1
line2
line3
line4
line5
line6
line7
line8
....

Je souhaiterais les grouper par ex par 4 en ajoutant un caractere style "|" tel que (fichier résultant)

line1|line2|line3|line4
line5|line6|line7|line8
....

J'ai chercher un moment mais pas trouvé :-((
Merci beaucoup par avance
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
M&amp;M Messages postés 5038 Date d'inscription dimanche 11 août 2002 Statut Contributeur Dernière intervention 3 décembre 2009 667
7 avril 2005 à 21:18
Je ne suis pas à la maison et n'ai pas testé ma réponse; essaye ce script Awk :
BEGIN {i=0}
//   {l=l $0 "|";
      if (i++>3) {
        print l "|" $0;
        l="";i=0
     }}
END {
  if (i>0) {print l}
}
 _ç_§: 
(.)#(.)
0
Super !
Merci. Impressionnant :-)
Ca me semble une bonne base.
Il faut maintenant que j'arrive a comprendre pourquoi il met 2 fois le dernier item ....

C:\TEMP\_ocs>gawk -f script.awk exemple.txt
Line1|Line2|Line3|Line4|Line5||Line5
Line6|Line7|Line8|Line9|Line10||Line10
Line11|Line12|Line13|Line14|Line15||Line15
Line16|Line17|Line18|Line19|Line20||Line20
Line21|Line22|Line23|Line24|Line25||Line25
Line26|Line27|Line28|Line29|Line30||Line30
Line31|Line32|Line33|Line34|Line35||Line35
Line36|Line37|Line38|Line39|Line40||Line40

Patrick
0
J'arrive a:
C:\TEMP\_ocs>gawk -f script2.awk exemple.txt
Line1|Line2|Line3|Line4|
Line5|Line6|Line7|Line8|
Line9|Line10|Line11|Line12|
Line13|Line14|Line15|Line16|
Line17|Line18|Line19|Line20|
Line21|Line22|Line23|Line24|
Line25|Line26|Line27|Line28|
Line29|Line30|Line31|Line32|
Line33|Line34|Line35|Line36|
Line37|Line38|Line39|Line40|

avec
BEGIN {i=0}
// {l=l $0 "|";
if (i++>2) {
print l;
l="";i=0
}}
END {
if (i>0) {print l}

Pas mal du tout même si je ne comprends pas tout: pourquoi dois-je descendre à 2 ( if (i++>2) pour avoir 4 lignes ?
Je continue. Merci
0
M&amp;M Messages postés 5038 Date d'inscription dimanche 11 août 2002 Statut Contributeur Dernière intervention 3 décembre 2009 667
10 avril 2005 à 17:22
Je ne vois pas bien pourquoi, à moins que ce ne soit l'ordre d'élaboration de l'opération, alors je sors l'incrémentation de l'expression conditionnelle. Je vois encore un tiret en trop en fin de chaque ligne. Ceci répond à ta demande initiale :
// {i++; 
    if (i==1) {ln=$0}
    else {ln=ln "|" $0
    }
    if (i>3) {print ln;ln="";i=0}
   }
END {  if (i>0) {print ln}
}
_ç_§:
(.)#(.)
0
Bonjour,
mon problème va sur ment être très simple pour la plus pard. J'ai une chaine de caractère dénommé ligne_info et je dois trouver si cette ligne est déjà existente dans une database. Si elle ne l'est pas, je dois l'inscrire.

voici ce que je pense être la bonne ligne mes ca ne fonctionne pas:

gawk -F: -v var= "$ligne_info" ' $0 != $var {print $var} ' database>database

Merci de bien réponde rapidement puisque je dois remettre ce travail assez rapidment.
0