173 votes

Comment extraire une colonne d'un fichier CSV

Si j'ai un fichier csv, existe-t-il un moyen rapide en bash d'imprimer le contenu d'une seule colonne ? On peut supposer en toute sécurité que chaque ligne a le même nombre de colonnes, mais le contenu de chaque colonne aurait une longueur différente.

0voto

qneill Points 347

Utilise ce code depuis un moment, ce n'est pas "rapide" sauf si tu comptes "copier-coller depuis stackoverflow".

Il utilise les opérateurs ${##} et ${%%} dans une boucle au lieu de IFS. Il appelle 'err' et 'die', et ne prend en charge que les caractères de séparation virgule, tiret et barre verticale (c'est tout ce dont j'avais besoin).

err()  { echo "${0##*/}: Erreur:" "$@" >&2; }
die()  { err "$@"; exit 1; }

# Retourner le N-ième champ dans une chaîne CSV, les champs numérotés à partir de 1
csv_fldN() { fldN , "$1" "$2"; }

# Retourner le N-ième champ dans une chaîne de champs séparés par SEP, les champs numérotés à partir de 1
fldN() {
        local me="fldN: "
        local sep="$1"
        local fldnum="$2"
        local vals="$3"
        case "$sep" in
                -|,|\|) ;;
                *) die "$me: arg1 sep: séparateur '$sep' non pris en charge" ;;
        esac
        case "$fldnum" in
                [0-9]*) [ "$fldnum" -gt 0 ] || { err "$me: arg2 fldnum=$fldnum doit être un nombre supérieur ou égal à 0."; return 1; } ;;
                *) { err "$me: arg2 fldnum=$fldnum doit être un nombre"; return 1;} ;;
        esac
        [ -z "$vals" ] && err "$me: arg2 vals manquant: liste de valeurs séparées par '$sep'" && return 1
        fldnum=$(($fldnum - 1))
        while [ $fldnum -gt 0 ] ; do
                vals="${vals#*$sep}"
                fldnum=$(($fldnum - 1))
        done
        echo ${vals%%$sep*}
}

Exemple:

$ CSVLINE="exemple,champs avec espace,champ3"
$ $ for fno in $(seq 3); do echo champ$fno: $(csv_fldN $fno "$CSVLINE");  done
champ1: exemple
champ2: champs avec espace
champ3: champ3

0voto

K. Sopheak Points 17933

Vous pouvez également utiliser la boucle while

IFS=,
while read name val; do
        echo "............................"

        echo Nom : "$name"
done

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X