Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/05/2007, 18h26   #1
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 22
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 22
Points : 10
Points : 10
Par défaut Traiter les champs d'un fichier conséquent

Bonjour,

Je dispose d'un fichier csv assez conséquent (100.000 lignes pour 150 colonnes environ)
Chaque ligne représente un ensemble de données.
Je souhaite créer nbColonnes - 1 fichiers représentants la liste des valeurs de chacun de ces champs(sans doublon) suivant le champ n°6 par exemple.
J'ai tenté deux essais (un avec "awk" & "sed", l'autre avec "cut") mais le traitement reste tres lent (+ de 5minutes pour "cut" et bcp plus pour l'autre technique).

Voici mes deux codes

Code essai avec sed & awk :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/sh
#
# Copyright (c) 2007, by bibi
# All rights reserved
 
fichier=$1
constructeur=$2
societe=$3
 
 
# Suivant le type de constructeur, la liste des index des champs ainsi que la position
# à laquelle se trouve l'indice représentant le type de ticket ne sont pas les mêmes.
 
nbLignes=`wc -l $fichier | awk -F" " '{printf $1}'`;
echo $nbLignes
indice=1
case $constructeur in
    a) 
        indiceTypeTicket=6
	nbChamps=170
	while [ $indice -lt nbChamps ]
	do		
	    echo "ticket : $indice"
	    sed "$indice!d" $fichier > ligne.tmp
	    for i in 7 8 9 10 ... 170 
	    do
  		val=`eval awk -F\\"\\;\\" \\'\\{print \\$$indiceTypeTicket\\,\\$$i}\\' ligne.tmp | sort -u >> $HOME/$constructeur/$societe/$i.champ`
	    done
	    (( indice = indice + 1))
	done
	break
	;;
    b)
	...
        # quasiment la même chose
	break
	;;
    c)
	...
        # quasiment la même chose
	break
esac


Code avec cut :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
#!/bin/sh
#
# Copyright (c) 2007, by bibi
# All rights reserved
# Script permettant de mettre à jour les fichiers décrivants la liste des valeurs possibles des champs d'un ticket
# Il prends en paramètre un fichier décrivant un ensemble de tickets, le constructeur et la société pour ces tickets.
 
fichier=$1
constructeur=$2
societe=$3
 
 
# fonction qui met à jour les fichiers décrivants la liste des valeurs possibles pour tous les
# champs du fichier en argument
miseAJourListe()
{
    echo "champ : $i"
    cut -d";" -f $1,$indiceTypeTicket $fichier | sort | uniq >> $HOME/$constructeur/$societe/$1.champ
}
#
 
# Suivant le type de constructeur, la liste des index des champs ainsi que la 
# position à laquelle se trouve l'indice représentant le type de ticket ne sont pas les mêmes.
case $2 in
    a) 
        indiceTypeTicket=6
	for i in 7 8 9 ... 170
	do
  	    miseAJourListe $i
	done
	break
	;;
    b)
	...
        # quasiment la même chose
	break
	;;
    c)
	...
        # quasiment la même chose
	break
    *)
	echo "Erreur constructeur"
	break
	;;
esac


Je ne sais que faire.... J'ai tenté une solution en java qui n'a pas été concluante et j'hésite à passer au C


EDIT: Un exemple de ce que je souhaiterais

le fichier est
a;b;c
0;2;5
1;7;3
1;5;3

et je voudrais 2 fichiers
1er fichier:
c;a
5;0
3;1
2eme fichier
c;b
5;2
3;7
3:5

ReEDIT: J'ai oublié de préciser que c'est le "sed" qui fait traîner le premier script
darkrio est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2007, 23h16   #2
Membre expérimenté
 
Avatar de BlaireauOne
 
Inscription : mars 2007
Messages : 469
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2007
Messages : 469
Points : 576
Points : 576
Citation:
Envoyé par darkrio
Un exemple de ce que je souhaiterais

le fichier est
a;b;c
0;2;5
1;7;3
1;5;3

et je voudrais 2 fichiers
1er fichier:
c;a
5;0
3;1
2eme fichier
c;b
5;2
3;7
3:5

Si j'ai bien compris, morceau de code qui doit marcher
http://lea-linux.org/cached/index/Dev-awk.html

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
.../...
TotEnreg=`wc -l < $fichier`
case $constructeur in
    a) 
  	awk -F";" -v TotEnreg=$TotEnreg -v indiceTypeTicket=3 '
	{
		Ind=0
		while (Ind < NF) {
			Ind++
			if (Ind == indiceTypeTicket) {
				continue
			}
			EdInd=sprintf("%3.3d",Ind)
			OutFile=EdInd".champ"
			print $indiceTypeTicket";"$Ind > OutFile
			if (NR == TotEnreg) {
				system("sort -u -o "OutFile" "OutFile)
			}
		}
	} ' $fichier
.../...
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2007, 11h10   #3
Candidat au titre de Membre du Club
 
Inscription : février 2007
Messages : 22
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 22
Points : 10
Points : 10
Merci, mais ton script est encore trop lent (plus lent que celui utilisant cut)
Est-il donc possible d'ecrire un script plus rapide ou me conseillez vous de passer à un programme en C
darkrio est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h46.


 
 
 
 
Partenaires

Hébergement Web