Concaténation en ksh

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. Contributeur
    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. 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. 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. 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. Contributeur
      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. Contributeur
      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. 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
    1. Contributeur
      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
      1. 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. 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. ksh n'est pas installé sur mon syno... je testerai de toutes façon au boulot lundi

          en tout merci pour ton aide ;)
          0
      2. Contributeur
        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