17/02/2024Si vous avez besoin d'analyser régulièrement des fichiers de type CSV, voici un script qui permet de le faire automatiquement.
Le script proposé ici analyse un fichier CSV depuis un serveur Linux, en utilisant Bash :
- Il détermine le séparateur (virgule ou point virgule)
- Il gère les champs échappés par des guillemets
- Il détermine le type de chaque colonne parmi entier, flottant, booléen, chaîne
- Il calcule les tailles mini et maxi de chaque colonne (en nombre de caractères)
- Il affiche, pour chaque colonne, les X premières lignes afin d'en vérifier le contenu
Utilisation
Son utilisation est relativement toute simple :
analyse_csv.sh <chemin_du_fichier> <nombre_de_lignes_affichées> <nombre_de_lignes_analysées>
- Chemin du fichier : pas besoin d'explication...
- Nombre de lignes affichées : pour chaque colonne, nombre de lignes affichées à l'écran
- Nombre de lignes analysées : pour chaque colonne, nombre de lignes servant à déterminer la taille mini/maxi et le type
Script
#!/bin/bash
#
# Analyse de fichier csv
# v1.0 - Eric Quillévéré - Février 2024
#
# Paramètres : <chaine:chemin du fichier> <int:nombre de lignes de détail affichées> <int:nombre de lignes analysées>
# Exemple d'appel : analyse_csv /opt/data/fichier.csv true
csv="$1"
nb_lignes_affichees="$2"
nb_lignes_analysees="$3"
if [ -z "$csv" ]; then
echo "Veuillez spécifier le chemin vers le fichier CSV en tant que premier argument."
exit 1
fi
if [ ! -f "$csv" ]; then
echo "Le fichier $csv n'existe pas."
exit 1
fi
if [ -z "$nb_lignes_affichees" ]; then
nb_lignes_affichees=0
fi
if [ -z "$nb_lignes_analysees" ]; then
nb_lignes_analysees=10000
fi
# Détection automatique du séparateur
separator=$(awk 'NR==1{if(index($0, ",") > 0) sep=","; else if(index($0, ";") > 0) sep=";"; else sep="UNKNOWN"; print sep; exit}' "$csv")
if [ "$separator" == "UNKNOWN" ]; then
echo "Séparateur inconnu dans la première ligne du fichier CSV."
exit 1
fi
# Compte le nombre de colonnes
nb_col=$(awk -F"$separator" '{print NF; exit}' "$csv")
echo -------------------------
echo Fichier "$csv" :
echo - Le séparateur est "$separator"
echo - Le nombre de colonnes est de $nb_col
echo - Le nombre de lignes analysées est $nb_lignes_analysees
echo
# Parcours les colonnes
for ((num_col = 1; num_col <= nb_col; num_col++)); do
col_name=$(awk -F"$separator" -v col="$num_col" 'NR==1{print $col; exit}' "$csv")
# Calcul de la taille mini-maxi des lignes pour la colonne en cours
# Détermine le type (booléen, entier, flottant, chaîne)
read min max type <<< $(awk -v col="$num_col" -v sep="$separator" -v nb_lig_anal="$nb_lignes_analysees" '
BEGIN {
min=99999;
max=0;
is_boolean = 1;
is_integer = 1;
is_float = 1;
is_affecte = 0;
}
NR>1 && NR<=nb_lig_anal {
i=1; j=1; inquotes=0; field=1; taille=0; deb=-1; point_trouve=0;
while(i<=length($0) && field<=col)
{
if(substr($0, i, 1) == "\"")
{
inquotes=!inquotes;
}
else if(substr($0, i, 1) == sep && !inquotes)
{
field++;
}
else if(field==col)
{
if (deb == -1)
deb=i;
if (substr($0, i, 1) < "0" || substr($0, i, 1) > "9")
{
is_integer=0;
if (substr($0, i, 1) == ".")
point_trouve++;
}
taille++;
}
i++;
}
if (taille<min) min=taille;
if (taille>max) max=taille;
if (taille>0)
{
chaine = substr($0, deb, taille);
is_affecte=1;
if (is_boolean==1 && !(chaine=="true" || chaine=="false"))
is_boolean=0;
if (is_float==1 && point_trouve!=1)
is_float=0;
}
}
END {
if (!is_affecte)
type="non affecté";
else if (is_boolean && (max==4 || max==5))
type="booléen";
else if (is_float)
type="flottant";
else if (is_integer)
type="entier";
else
type="chaîne";
# Convertir en minuscules
type = tolower(type);
print min, max, type;
}' "$csv")
printf "%d. %s (%s, de %d car. à %d car.) \n" "$num_col" "$col_name" "$type" "$min" "$max"
# Si détail demandé, affichage des X premières lignes
if [ "$nb_lignes_affichees" -gt 0 ]; then
awk -v col="$num_col" -v sep="$separator" '{
i=1; j=1; inquotes=0; field=1;
while(i<=length($0) && field<=col) {
if(substr($0, i, 1) == "\"") {
inquotes=!inquotes;
} else if(substr($0, i, 1) == sep && !inquotes) {
field++;
} else if(field==col) {
printf "%s", substr($0, i, 1);
}
i++;
}
printf "\n";
}' "$csv" | tail -n +2 | head -n $nb_lignes_affichees
if [ "$num_col" -lt "$nb_col" ]; then
read -p " Appuyez sur [ENTREE]..."
fi
echo
fi
done
Exemples
Extraction de la liste des colonnes
Il faut appeler le script avec comme unique paramètre le chemin du fichier :
Affichage des premières valeurs de chaque colonne
Il faut appeler le script avec comme paramètres le chemin du fichier et le nombre de lignes à afficher :
Après l'appui sur Entrée, les 10 premières valeurs de la colonne suivante s'affichent :
Dernière modification le 17/02/2024 - Quillevere.net