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

dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
Flachy Joe Messages postés 2102 Date d'inscription   Statut Membre Dernière intervention   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
yepimback Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
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
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
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
Flachy Joe Messages postés 2102 Date d'inscription   Statut Membre Dernière intervention   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
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
yepimback Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
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
Flachy Joe Messages postés 2102 Date d'inscription   Statut Membre Dernière intervention   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
yepimback Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
ksh n'est pas installé sur mon syno... je testerai de toutes façon au boulot lundi

en tout merci pour ton aide ;)
0

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

Posez votre question
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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