Utilitaires
Scripts
Divers
Jeux
Rechercher
Quillevere.net
Paradigmes informatiques

Afficher la structure d'un fichier CSV en ligne de commande Linux

17/02/2024
Si 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

Commentaires

Aucune inscription n'est requise si vous souhaitez

Rechercher sur le site

fr en rss RSS info Informations