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 27/07/2007, 14h56   #1
Invité de passage
 
Inscription : février 2003
Messages : 7
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 7
Points : 1
Points : 1
Par défaut Optimisation lecture fichier via un shell script

Bonjour,

J'ai actuellement un fichier d'entrée de 5 000 000 de lignes environ du type :

A;B;C;D;E...
A;B;C;D;F...
B;C;D;E;F...

Ce fichier doit être décomposé en sous-fichiers selon une clé définie par exemple les 2 premiers champs et, ce qui est mon pb le plus rapidement possible.

J'ai essayé en shell script, puis en awk mais les temps de traitement sont toujours trop lents.
Quelle est la méthode la plus efficace pour effectuer un tel traitement ? et quelle durée puis-je espérer pour effectuer ce traitement ?

Merci d'avance.
macleod est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2007, 15h14   #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
Es-tu sûr que le code de ton awk est optimisé au maximum ?
Si ce n'est pas indiscret, peux-tu le mettre en ligne, au cas où
__________________
Loi de Murphy:
La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2007, 15h31   #3
Invité de passage
 
Inscription : février 2003
Messages : 7
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 7
Points : 1
Points : 1
Un extrait du code utilisé :

Code :
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 
#!/usr/bin/ksh
#set -x
 
if [ -z "$Col1" ];then Col1=1;fi
if [ -z "$Col2" ];then Col1=1;fi
if [ -z "$CptLig" ];then CptLig=0;fi
 
Nom1="fichier1.out"
Nom2="fichier2.out"
Rep=$PWD
 
calculerNomFichier()
{
        NomFicSortie="${ColX}${ColY}${ColZ}XXX.txt"
 
}
 
writeCorps  ()
{
        CptLig=$(($CptLig + 1))
        #Structure du corps en sortie
        echo "${Bloc1};${Col4};${Col5};${Bloc2};" >> ${NomFicSortie}
}
 
cd ${Rep}
 
#initialisation Variables de rupture
IdPrec=""
MPrec=""
APrec=""
 
#Concatenation des 2 fichiers en entrée pour réaliser une boucle de traitement
Liste="${Nom1} ${Nom2}"
 
#boucle de traitement des fichiers
for Nom in ${Liste}
do
    echo ""
    echo "Traitement de ${Nom} Debut $(date '+%H:%M:%S')"
    echo ""
 
        #Lecture des fichiers en entrée et split des champs par awk
        awk -F"?" '{ print $1,$2,$3,$3,$4,$5,$6 }' $Nom | while read -r Bloc1 Col6 Col7 Coll8 Col9 Col10 Bloc2
        do
            if [ "${IdPrec}" =  "${Col1}" -a  "${Col2}" =  "${Col3}" -a  "${Col4}" =  "${Col5}" ]
            then
                writeCorps
 
            #Sinon on crée un nouveau fichier, on ecrit :
            #   une ligne d'entete
            #   la 1ere ligne du corps
            else
 
                #incrément de Num
                if [ "${IdPrec}" =  "${Col1}" ]
                then
                    Num=$(($Num + 1))
                    #echo "Incrément du Num à $Num"
                else
                    Num=1
                fi
 
                IdPrec=${Col1}
                MPrec=${Col2}
                APrec=${Col3}
                calculerNomFichier
                echo "XXX;YYYY${Num}$(echo $(date '+%H%S'));ZZZZ;$(echo $(date '+%d/%m/%Y %H:%M'));${Col4} 6:00-${Col5} 6:00;BBBB;${Col6};AAA;"  > ${NomFicSortie}
                writeCorps
          fi
    done
done
 
echo ""
echo "Execution `basename $0` terminee at $(date '+%H%M%S') pour $CptLig lignes"
echo ""
 
exit 0
macleod est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2007, 17h28   #4
Candidat au titre de Membre du Club
 
Inscription : juillet 2007
Messages : 34
Détails du profil
Informations forums :
Inscription : juillet 2007
Messages : 34
Points : 10
Points : 10
Moi en shell...

Je verrais bien l'utilisation suivante...

un cat fic.txt
un cut -d";" -f1 (pour recuperer toute la 1ere col)
un cut -d";" -f2 (.....)

bref...en gros utiliser cut...avec delimiteur ; ou sinon, awk avec delimiteur
magicwill est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/07/2007, 20h14   #5
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
Ce qui est assez coûteux, c'est le double accès sur les données :
1er par awk
2ème par "while read"

Code :
awk -F"?" '{ print $1,$2,$3,$3,$4,$5,$6 }' $Nom | while read -r Bloc1 Col6 Col7 Coll8 Col9 Col10 Bloc2
Solution tout en awk qui devrait être plus rapide
http://www.shellunix.com/awk.html
http://lea-linux.org/cached/index/Dev-awk.html
http://pwet.fr/man/linux/commandes/posix/awk


Obs : ${Col4} et ${Col5} utilisées et pas déclarées...


Code :
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
 
Nom1="fichier1.out"
Nom2="fichier2.out"
 
#Concatenation des 2 fichiers en entrée pour réaliser une boucle de traitement
Liste="${Nom1} ${Nom2}"
 
 
awk -F"?" -v AAAA=$(date +%H%S) -v script=$(basename $0) '
function writeCorps()
{
	#Structure du corps en sortie
	# A adapter !!!!!!!!!!
	print $1";"$4";"$5";"$2";" > NomFicSortie
}
BEGIN {
	IdPrec=""
	MPrec=""
	APrec=""
}
#------------------------------------------------------------#
#                      PROCEDURE PRINCIPALE                  #
#------------------------------------------------------------#
{
	if (FILENAME != FILEprec) {
		print ""
		TimeStamp="'$(date +%d/%m/%Y_%H:%M)'"
		print "Traitement de "FILENAME" Debut "TimeStamp
		print ""
		FILEprec=FILENAME
	}
	if ($1 == IdPrec && $2 == MBrec && $3 == APrec) {
		# Bloc1 Col6 Col7 Coll8 Col9 Col10 Bloc2
		writeCorps()
		next #-- on passe à l enregisrement suivant
	} 
	#
	### Changement de fichier de sortie
	#
	if ($1 == IdPrec) {
		Num=1
	} else {
		Num++
	}
	IdPrec=$1
	MPrec=$2
	APrec=$3
	NomFicSortie=$1""$2""$3"XXX.txt"
	TimeStamp="'$(date +%d/%m/%Y_%H:%M)'"
	print "XXX;YYYY"Num"AAAA;ZZZZ;"TimeStamp";"$4" 6:00-"$5" 6:00;BBBB;"$6";AAA;" > NomFicSortie
	writeCorps()
 
}
#------------------------------------------------------------#
#                  FIN PROCEDURE PRINCIPALE                  #
#------------------------------------------------------------#
END {
	print ""
	TimeStamp="'$(date +%d/%m/%Y_%H:%M)'"
	print "Execution "script" terminee at "TimeStamp" pour "NR" lignes"
	print ""
} ' $Liste
 
exit 0
__________________
Loi de Murphy:
La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.
BlaireauOne est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/07/2007, 12h46   #6
Invité de passage
 
Inscription : février 2003
Messages : 7
Détails du profil
Informations forums :
Inscription : février 2003
Messages : 7
Points : 1
Points : 1
Merci beaucoup pour tes liens.

Je suis en cours de tests pour tout exécuter en awk.

Rq : Pour les Col4 et Col5, j'ai un peu modifié le script avant le post pour ne pas tout afficher d'où quelques pbs non présents dans la version originale.
macleod 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 20h28.


 
 
 
 
Partenaires

Hébergement Web