Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 15/06/2016, à 17: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, à 17: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, à 18:22)

Hors ligne

#3 Le 15/06/2016, à 19: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 16/06/2016, à 00:08)

#4 Le 15/06/2016, à 23: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 16/06/2016, à 00:02

Compte anonymisé

Re : [Bash] Concaténer champs selon une colonne

en effet, je corrige.

#6 Le 16/06/2016, à 06: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, à 09: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, à 09: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