#1 Le 15/06/2016, à 16:00
- Chartreuse
[Bash] Concaténer champs selon une colonne
Bonjour,
J'ai un fichier CSV qui ressemble à cela :
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte [...]
Dans ce fichier il y a des numéros de téléphone identiques.
Je souhaite avoir des numéros de téléphone unique et regrouper les autres paramètres dans des tableaux. Par exemple :
Fichier entrée :
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte
01/01/15;31/01/15;blabla;01/03/15;0102030405;abc
24/11/14;15/01/16;albalb;02/08/15;0504030201;cba
27/09/16;01/08/16;balbal;04/04/14;0102030405;bca
Fichier sortie :
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte
[01/01/15,27/09/16];[31/01/15,01/08/16];[blabla,balbal];[01/03/15,04/04/14];0102030405;[abc,bca]
[24/11/14];[15/01/16];[albalb];[02/08/15];0504030201;[cba]
J'ai voulu commencer par trier mon fichier csv sur les numéros de téléphone pour que le traitement soit plus facile par la suite mais comme il s'agit de numéros de téléphone à trier, la commande sort me rend mon fichier tel quel.
Est-ce qu'une gentille âme pourrait m'aider ?
Hors ligne
#2 Le 15/06/2016, à 16:07
- pingouinux
Re : [Bash] Concaténer champs selon une colonne
Bonjour,
Déjà, pour trier le fichier suivant les numéros de téléphone (5ème champ)
sort -t\; -k5 fichier.csv
La première ligne va se trouver déplacée aussi.
Ajouté : Personnellement, je ferais ça en python. Est-ce un exercice de cours ?
Dernière modification par pingouinux (Le 15/06/2016, à 17:22)
Hors ligne
#3 Le 15/06/2016, à 18:32
- Compte anonymisé
Re : [Bash] Concaténer champs selon une colonne
Bonjour,
je propose ce script (attention le code n'est probablement pas optimal)
#!/bin/bash
file=fichier.csv
fonction()
{
for ((i=1;i<=$nb;i++))
do
if [ "$i" = 1 ]
then printf "["
else printf ","
fi
printf "$(awk '/'$a'/{j++}j=='$i'{print; exit}' "$file"|cut -d";" -f"$1")"
[ "$i" = "$nb" ]&&printf "]"
done
}
head -1 "$file"
for a in $(tail -n +2 "$file"|cut -d";" -f5|sort -u)
do nb=$(grep "$a" "$file"|wc -l)
fonction 1
printf ";"
fonction 2
printf ";"
fonction 3
printf ";"
fonction 4
printf ";$a;"
fonction 6
echo
done
essai avec l'exemple :
$ cat fichier.csv
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte
01/01/15;31/01/15;blabla;01/03/15;0102030405;abc
24/11/14;15/01/16;albalb;02/08/15;0504030201;cba
27/09/16;01/08/16;balbal;04/04/14;0102030405;bca
$ bash test.sh
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte
[01/01/15,27/09/16],[31/01/15,01/08/16],[blabla,balbal],[01/03/15,04/04/14],0102030405,[abc,bca]
[24/11/14],[15/01/16],[albalb],[02/08/15],0504030201,[cba]
Dernière modification par Compte anonymisé (Le 15/06/2016, à 23:08)
#4 Le 15/06/2016, à 22:27
- MicP
Re : [Bash] Concaténer champs selon une colonne
Il faudrait juste remplacer cet extrait :
…
printf ","
fonction 2
printf ","
fonction 3
printf ","
fonction 4
printf ",$a,"
…
par ce qui suit :
printf ";"
fonction 2
printf ";"
fonction 3
printf ";"
fonction 4
printf ";$a;"
Hors ligne
#5 Le 15/06/2016, à 23:02
- Compte anonymisé
Re : [Bash] Concaténer champs selon une colonne
en effet, je corrige.
#6 Le 16/06/2016, à 05:51
- Watael
Re : [Bash] Concaténer champs selon une colonne
et si on faisait ça avec l'outil le mieux adapté pour traiter un fichier CSV ?
#!/usr/bin/awk -f
BEGIN{ FS=";" }
{
if(FNR==1){
print
} else {
fi[$5] = ($5 in fi) ? fi[$5]";"$1 : $1
se[$5] = ($5 in se) ? se[$5]";"$2 : $2
th[$5] = ($5 in th) ? th[$5]";"$3 : $3
fo[$5] = ($5 in fo) ? fo[$5]";"$4 : $4
si[$5] = ($5 in si) ? si[$5]";"$6 : $6
wh[$5] = "["fi[$5]"];["se[$5]"];["th[$5]"];["fo[$5]"];"$5";["si[$5]"]"
}
}
END{
W=asorti(wh,WH)
for(i=1;i<=W;i++)print wh[WH[i]]
}
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#7 Le 16/06/2016, à 08:23
- Chartreuse
Re : [Bash] Concaténer champs selon une colonne
Merci à tous.
Je souhaite faire des statistiques sur ces fichiers et je pensais que bash était bien adapté.
Je trouve la commande awk extrêmement puissante mais très (trop) complexe. Je pense qu'il faut que je monte en compétences dessus.
Hors ligne
#8 Le 16/06/2016, à 08:29
- pingouinux
Re : [Bash] Concaténer champs selon une colonne
Avec python :
$ cat concat.py
import sys
ligs=sys.stdin.readlines()
print(ligs[0][:-1])
resul={}
for lig in ligs[1:]:
ligspl=lig[:-1].split(';')
tel=ligspl[4]
if tel not in resul:
resul[tel]=[]
for k in range(len(ligspl)): resul[tel].append([])
for k in range(len(ligspl)): resul[tel][k].append(ligspl[k])
for tel in sorted(resul):
s=[]
for elem in resul[tel]:
s.append("["+",".join(elem)+"]" if elem[0]!=tel else tel)
print("%s"%";".join(s))
À lancer ainsi :
python concat.py <fichier.csv
Voici le résultat avec ton exemple en #1 :
Date1 ; Date2 ; Texte ; Date3 ; Numéro de téléphone ; Texte
[01/01/15,27/09/16];[31/01/15,01/08/16];[blabla,balbal];[01/03/15,04/04/14];0102030405;[abc,bca]
[24/11/14];[15/01/16];[albalb];[02/08/15];0504030201;[cba]
Hors ligne