Concaténation en ksh

yepimback -  
 yepimback -
Bonsoir,

je me trouve face à un problème:

j'ai deux fichiers avec plusieurs lignes avec une seule chaîne de caractères commune aux deux.

cat fic1
25678;type1;harrys;6789;hji
67890;type4;uname;6799;kloo
67890;type3;basic;6089;lois

cat fic2
udhk;juikop;cassiop;768888
khkq;skdjh;99900;6789
qdsss;uuud;uname;uioo
67890;jjuii;sdds;00097

comment faire pour avoir un seul fichier dont se suivent les lignes qui ont les caractères communs?

exemple de sortie (new_file):
25678;type1;harrys;6789;hji
khkq;skdjh;99900;6789

67890;type4;uname;6799;kloo
qdsss;uuud;uname;uioo

67890;type3;basic;6089;lois
67890;jjuii;sdds;00097

je sèche... j'ai même pas la moindre petite idée...

merci pour votre aide

5 réponses

  1. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 659
     
    essayer avec awk
    $ awk -F ";" 'FNR==NR {t[++l]=$0; next} {for(n=1; n<=l;n++){if(!t[n])continue; split(t[n], a); for(m=1; m<=NF; m++)if(a[m]==$m){print $0 RS t[n]; t[n]=""}} next}' fic2 fic1
    25678;type1;harrys;6789;hji
    khkq;skdjh;99900;6789
    67890;type4;uname;6799;kloo
    qdsss;uuud;uname;uioo
    67890;type4;uname;6799;kloo
    67890;jjuii;sdds;00097
    $ 
    
    1
    1. Flachy Joe Messages postés 2303 Statut Membre 261
       
      Ah ben si il y a un maître de awk, je m'incline bien bas ;-)

      J'ai d'ailleurs dit l'autre fois que si on faisait une boucle dans un script c'est qu'on avait raté quelque chose...
      0
    2. yepimback Messages postés 4 Statut Membre
       
      C'est à moi de m'incliner bien bas...! Chapeau. Je m'attendais effectivement à un awk mais celui là faut aller le chercher loin et chui nul...
      Des que j'ai mon Pc sous la main j'essaye. Tu peux expliquer grossièrement?

      1000 merci
      0
    3. yepimback
       
      Re
      je viens d'essayer... malheureusement pour les très gros fichiers de plusieurs ko ça ne me rend jamais la main après 10 minutes. et quand je fais un top (HPUX) je m'aperçois que c'est extrêmement consommateur de cpu.
      il doit y a voir un truc qui va pas :(

      j'y retourne :)
      0
    4. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 659
       
      effectivement, pour chaque ligne de fic1, il teste chaque champs de fic1 avec chaque champ de chaque ligne de fic2; si il y a un champ égal, on imprime les 2 lignes et on met la ligne de fic2 à 0 pour ne plus la tester.
      comment faire autrement ?
      0
    5. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 659
       
      j'ai déplacé le dernier next pour sortir plus vite de la boucle quand un champ est trouvé
      awk -F ";" 'FNR==NR {t[++l]=$0; next} {for(n=1; n<=l;n++){if(!t[n])continue; split(t[n], a); for(m=1; m<=NF; m++)if(a[m]==$m){print $0 RS t[n]; t[n]=""; next}}}' fic2 fic1
      0
  2. Flachy Joe Messages postés 2303 Statut Membre 261
     
    Salut,
    je sais pas si c'est le plus simple, mais ça fonctionne :
    #!/bin/bash
    
    t1="25678;type1;harrys;6789;hji
    67890;type4;uname;6799;kloo
    67890;type3;basic;6089;lois"
    
    f2="test.tmp"
    echo "udhk;juikop;cassiop;768888
    khkq;skdjh;99900;6789
    qdsss;uuud;uname;uioo
    67890;jjuii;sdds;00097" > $f2
    
    std_IFS=$IFS
    
    for l in $t1
    do
     IFS=";"
     for pattern in $l
     do
      res=$(egrep "\<${pattern}\>" $f2)
      if [ -n "$res" ]
      then
       echo "$l"
       echo "$res"
       echo 
      fi
      unset res
     done;
     IFS=$std_IFS
    done;
    
    rm $f2
    


    ;-) Flachy Joe ;-)
    0
  3. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 659
     
    hello
    quand plusieurs lignes ont un champ commun, quel est le critère ? l'ordre des lignes ?
    cat fic1
    67890;type4;uname;6799;kloo
    67890;type3;basic;6089;lois
    
    cat fic2
    qdsss;uuud;uname;uioo
    67890;jjuii;sdds;00097
    
    0
  4. yepimback Messages postés 4 Statut Membre
     
    merci pour vos réponses:
    j'étais trop fatigué hier soir ... plus moyen de lire le moindre ls :/

    @dubcek
    le seul critère c'est que les lignes contenant au moins une chaîne de caractères en commun soit ensemble.
    dans ton exemple:
    cat fic1
    67890;type4;uname;6799;kloo
    67890;type3;basic;6089;lois

    cat fic2
    qdsss;uuud;uname;uioo
    67890;jjuii;sdds;00097

    => cat fic_final

    67890;jjuii;sdds;00097
    67890;type3;basic;6089;lois
    67890;type4;uname;6799;kloo
    qdsss;uuud;uname;uioo

    dans le mien normalement seul 2 champs sont identiques à chaque fois.

    @Flashy Joe:
    je n'ai pas bash d'installé, faudrait que je teste
    (je viens d'essayer en ash sur un synology et ça retourne rien... dommage parce que ça avait l'air pas mal... tu viens de me tendre un fil directeur ;) )

    Merci ;)
    0
    1. Flachy Joe Messages postés 2303 Statut Membre 261
       
      ksh est compatible bash, il suffit de changer la première ligne en
      #!/bin/ksh

      Résultat :
      flachy@biduloscope:~$ apt-cache show ksh
      Package: ksh
      Version: 93u+20120801-1
      [...]
      flachy@biduloscope:~$ ./test.sh
      25678;type1;harrys;6789;hji
      khkq;skdjh;99900;6789
      
      67890;type4;uname;6799;kloo
      67890;jjuii;sdds;00097
      
      67890;type4;uname;6799;kloo
      qdsss;uuud;uname;uioo
      
      67890;type3;basic;6089;lois
      67890;jjuii;sdds;00097
      
      
      0
    2. yepimback Messages postés 4 Statut Membre
       
      ksh n'est pas installé sur mon syno... je testerai de toutes façon au boulot lundi

      en tout merci pour ton aide ;)
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 659
     
    essayer cet algorithme, peut-être plus rapide, si il fonctionne bien !!
    $ awk -F ";" -v f=fic2 'BEGIN{nr=1; while(getline < f){for(n=1; n<=NF; n++)t[nr, $n]++; t2[nr++]=$0}} {for(l=1; l<nr; l++){split($0, a); for(m=1; m<=NF; m++)if(t[l, a[m]] && t2[l]){print $0 RS t2[l]; t2[l]=""; next}}}' fic1
    25678;type1;harrys;6789;hji
    khkq;skdjh;99900;6789
    67890;type4;uname;6799;kloo
    qdsss;uuud;uname;uioo
    67890;type3;basic;6089;lois
    67890;jjuii;sdds;00097
    $
    
    0