Concaténation en ksh

Fermé
yepimback - 12 juil. 2013 à 20:38
 yepimback - 15 juil. 2013 à 15:50
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 18753 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 7 novembre 2024 5 619
13 juil. 2013 à 13:16
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 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 260
Modifié par Flachy Joe le 13/07/2013 à 13:26
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 vendredi 12 juillet 2013 Statut Membre Dernière intervention 14 juillet 2013
13 juil. 2013 à 17:22
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
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 18753 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 7 novembre 2024 5 619
14 juil. 2013 à 09:27
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 18753 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 7 novembre 2024 5 619
14 juil. 2013 à 11:07
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 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 260
Modifié par Flachy Joe le 12/07/2013 à 22:37
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 18753 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 7 novembre 2024 5 619
Modifié par dubcek le 13/07/2013 à 09:23
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 vendredi 12 juillet 2013 Statut Membre Dernière intervention 14 juillet 2013
Modifié par yepimback le 13/07/2013 à 12:41
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 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 260
13 juil. 2013 à 13:02
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 vendredi 12 juillet 2013 Statut Membre Dernière intervention 14 juillet 2013
Modifié par yepimback le 13/07/2013 à 13:10
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 18753 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 7 novembre 2024 5 619
14 juil. 2013 à 15:36
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