cClaude.rocks ☕ Le blog

[Nouvelles technologies, sciences et coups de gueule…]

Menu

Le format CSV (Commat Separated Values) est un format de donnée disponible avec beaucoup de logiciels. Comme son nom l’indique, il s’agit d’un fichier où les champs sont simplement séparés par une virgule.

Historiquement la description du format CSV se limitait à cela et par exemple, il n’était pas possible d’avoir une virgule dans les données.

Pour contourner les problèmes du format de base de nombreuses évolutions ont été mises en place mais ce format n’a jamais vraiment fait l’objet d’une spécification formelle. Toutefois, la RFC 41801 décrit la forme la plus courante et établit son type MIME « text/csv ».


Il existe pas mal de solutions permet de convertir du CSV vers le format JSON, ici je vais m’attarder sur une solution demandant peu de dépendances et adapté au contexte du déploiement d’une machine. En particulier, une solution ne nécessitant pas l’installation de npm ou de pip.

csvkit

Installation de csvkit

Pour les plateformes Ubuntu et dérivées comme Linux-Mint:

sudo apt update && sudo apt install -y csvkit

Utilisation de csvkit

Pour convertir un fichier CSV en JSON, vous devrez utilise la commande csvjon du package csvkit.

csvjson [options] file.csv
  • Aide de csvjson

    L’aide complète s’obtient avec :

    csvjson --help
    
    usage: csvjson [-h] [-d DELIMITER] [-t] [-q QUOTECHAR] [-u {0,1,2,3}] [-b]
                   [-p ESCAPECHAR] [-z FIELD_SIZE_LIMIT] [-e ENCODING] [-L LOCALE]
                   [-S] [--blanks] [--date-format DATE_FORMAT]
                   [--datetime-format DATETIME_FORMAT] [-H] [-K SKIP_LINES] [-v]
                   [-l] [--zero] [-V] [-i INDENT] [-k KEY] [--lat LAT] [--lon LON]
                   [--crs CRS] [--stream] [-y SNIFF_LIMIT] [-I]
                   [FILE]
    
    Convertir un fichier CSV en JSON (ou GeoJSON).
    
    les arguments de position :
      FILE                  Le fichier CSV sur lequel opérer. S’il est omis,
                            l'entrée standard (STDIN) sera utilisée.
    
    les arguments facultatifs :
      -h, --help            Affiche ce message d’aide et quitte
      -d DELIMITER, --delimiter DELIMITER
                            Caractère de délimitation du fichier CSV d’entrée.
      -t, --tabs            Spécifiez que le fichier CSV d’entrée est délimité par
                            des tabulations. Remplace "-d".
      -q QUOTECHAR, --quotechar QUOTECHAR
                            Caractère utilisé pour citer les chaînes de caractères dans
                            le fichier CSV d’entrée.
      -u {0,1,2,3}, --quoting {0,1,2,3}
                            Style de citation utilisé dans le fichier CSV d’entrée.
                            0 = Citation Minimal,
                            1 = Citation All,
                            2 = Citation Non-numérique,
                            3 = Aucune citation.
      -b, --no-doublequote  Si les guillemets doubles sont doublés ou non dans le fichier
                            CSV d’entrée.
      -p ESCAPECHAR, --escapechar ESCAPECHAR
                            Caractère utilisé pour échapper au délimiteur si
                            --quoting 3 ("Quote None") est spécifié et pour échapper à
                            l'apostrophe QUOTECHAR si --no-doublequote est spécifié.
      -z FIELD_SIZE_LIMIT, --maxfieldsize FIELD_SIZE_LIMIT
                            Longueur maximale d’un champ unique dans le fichier CSV
      -e ENCODING, --encoding ENCODING
                            Précise l’encodage du fichier CSV d’entrée.
      -L LOCALE, --locale LOCALE
                            Précise la locale (en_US) de tous les nombres formatés.
      -S, --skipinitialspace
                            Ignore les espaces qui suivent immédiatement le délimiteur.
      --blanks              Ne pas convertir "", "na", "n/a", "none", "null", "." en NULL.
      --date-format DATE_FORMAT
                            Spécifie une chaîne de format de date strptime comme "%m/%d/%Y".
      --datetime-format DATETIME_FORMAT
                            Spécifie une chaîne de format de temps de date strptime
                            comme "%m/%d/%Y %I:%M %p".
      -H, --no-header-row   Définit que le fichier CSV d’entrée n’a pas de ligne d'en-tête.
                            Créera des en-têtes par défaut (a,b,c…).
      -K SKIP_LINES, --skip-lines SKIP_LINES
                            Indiquez le nombre de lignes initiales à ignorer
                            (par exemple, les commentaires, les avis de copyright, les lignes vides).
      -v, --verbose         Affiche des traces détaillées lorsque des erreurs se produisent.
      -l, --linenumbers     Insérez une colonne de numéros de ligne au début de la sortie.
                            Utile lors du piping vers grep ou comme simple clé primaire.
      --zero                Lorsque de l’interprétation ou l’affichage des numéros de colonnes,
                            utilise la numérotation basé sur zéro au lieu de la
                            numérotation basé sur 1 par défaut.
      -V, --version         Affiche les informations sur la version et quitte.
      -i INDENT, --indent INDENT
                            Indente la sortie JSON de ce nombre d’espaces.
                            Désactivé par défaut.
      -k KEY, --key KEY     Affiche le JSON sous la forme d’un tableau d’objets
                            avec une colonne donnée, KEY, plutôt que sous forme de
                            liste. Toutes les valeurs de la colonne doivent être uniques.
                            Si les options --lat et --lon sont également spécifiées,
                            cette colonne sera utilisée comme GeoJSON Feature ID.
      --lat LAT             Un index ou un nom de colonne contenant une latitude.
                            La sortie sera GeoJSON au lieu de JSON. Valable uniquement
                            si --lon est également spécifié.
      --lon LON             Un index ou un nom de colonne contenant une longitude.
                            La sortie sera GeoJSON au lieu de JSON. Valable uniquement si
                            --lat est également spécifié.
      --crs CRS             Une chaîne de système de référence de coordonnées à inclure
                            avec la sortie GeoJSON. Seulement valide si --lat et --lon
                            sont spécifiés.
      --stream              Affiche JSON comme un flux d’objets séparés par des nouvelles
                            lignes, plutôt que comme un tableau.
      -y SNIFF_LIMIT, --snifflimit SNIFF_LIMIT
                            Limite le reniflage des dialectes CSV au nombre spécifié de
                            d’octets. Spécifiez "0" pour désactiver entièrement le reniflage.
      -I, --no-inference    Désactiver l’inférence de type (et --locale, --date-format,
                            --datetime-format) lors de l’analyse des données CSV.
    

Alternative pour des fichiers CSV simples

Mise en place d’un convertisseur minimaliste avec jq

jq -R -s -f csv2json.jq FICHIER_CSV

Avec le fichier csv2json.jq:

  • Fichier: csv2json.jq
    #
    # csv2json.jq
    #
    # objectify/1 takes an array of string values as inputs, converts
    # numeric values to numbers, and packages the results into an object
    # with keys specified by the "headers" array
    def objectify(headers):
      # For jq 1.4, replace the following line by: def tonumberq: .;
      def tonumberq: tonumber? // .;
      . as $in
      | reduce range(0; headers|length) as $i ({}; .[headers[$i]] = ($in[$i] | tonumberq) );
    
    def csv2table:
      # For jq 1.4, replace the following line by:  def trim: .;
      def trim: sub("^ +";"") |  sub(" +$";"");
      split("\n") | map( split(",") | map(trim) );
    
    def csv2json:
      csv2table
      | .[0] as $headers
      | reduce (.[1:][] | select(length > 0) ) as $row
          ( []; . + [ $row|objectify($headers) ]);
    
    csv2json
    

Vous aurez tout loisir d’adapter la sortie l’aide d’autres filtres jq, comme ici :

jq -R -s -f csv2json.jq Downloads/contacts.csv |
  jq 'delpaths([path(.[][]| select(.==null))]) | delpaths([path(.[][]| select(.==""))])'
jq -R -s -f csv2json.jq Downloads/contacts.csv |
  jq 'walk( if type == "object" then with_entries(select(.value != null)) else . end)' input.json

Références

ᦿ


ℹ 2006 - 2022 | 🏠 Accueil du domaine | 🏡 Accueil du blog