Désolé, Tomtom, j'ai eu du mal à comprendre ton script.
Surtout il saute au yeux qu'il lit le fichier sans arret (head -1, tail , ...)
Il me semblait important de traiter le fichier en une seule lecture si possible.
Après un travail assez long, à me repencher sur le scripting bash, j'ai abouti à ceci (certes plus long mais plus rapide) :
- Code: Tout sélectionner
#!/bin/bash
#
# calcul des longueurs de champs
#
# le fichier a analyser est en parametre $1
FIC=$1
# declaration des variables
numch=0 # nb de champs (+1)
ch=(" ") # noms des champs
lg=(0) # longueurs max des champs
trchamp=1 # 1 pour la premiere ligne puis 0
# boucle de parcours du fichier (noter que le fichier est au "done" final)
while read ligne
do
OIFS=$IFS
# astuce : decoupage de $ligne grace au : (=$IFS)
IFS=":"
set $ligne
if [ "$trchamp" = "1" ]
then
# traiter la ligne des champs
numch=1
until [ -z "$1" ]
do
ch[$numch]=$1 # nom du champ
lg[$numch]=0
shift
numch=$[numch+1]
done
trchamp=0
else
# traiter les autres lignes
i=1
until [ -z "$1" ]
do
v=$1
l=${#v} # longueur du champ
if [ "$l" -gt "${lg[$i]}" ]
then
lg[$i]=$l
fi
shift
i=$[i+1]
done
fi
IFS=$OIFS
done <$FIC
# affichage resultat
i=1
while [ "$i" -lt $numch ]
do
echo "champ \"${ch[$i]}\" longueur max : ${lg[$i]}"
i=$[i+1]
done
A noter l'astuce essentielle :
IFS=":" -> séparateur :
set $ligne -> transformation de la variable en parametre ($x)
until [-z "$1] do ... shift; done -< boucle de parcours des paramêtres un par un !
J'ai copié ta syntaxe pour incrémenter mais j'écrit parfois "let "i+=1" qui marche aussi.
A noter que j'écris "while read do ... done <$FIC" et non "cat $FIC | while read do ... done".
Cela posait un sérieux problème de variable mis à jour à l'intérieur d'un sous-shell ;=)
J'ai mis un temps énnnnaurme (oui) à comprendre ce qui clochait.
J'ai testé : cela donne les mêmes résultats que mon script awk (ouf!). Mais awk est vraiment idéal.