delpaths
path
select
walk
type == "object" then with_entries(select(.value != null)) else . end)' input.json
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ée sur zéro au lieu de la numérotation basée 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
- Comma-separated values sur Wikipedia,
- CSV to JSON using jq,
- csvkit (csvkit 1.0.7 au moment de l’écriture de l’article),
- La FAQ de jq en anglais,
- Le manuel de jq en anglais (Vous pouvez choisir la version de jq).
ᦿ