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.

6voto

Soundbytes Points 685

Je me demande pourquoi aucun des réponses jusqu'à présent n'a mentionné csvkit.

csvkit est une suite d'outils en ligne de commande pour convertir et travailler avec des fichiers CSV

documentation de csvkit

Je l'utilise exclusivement pour la gestion des données csv et jusqu'à présent je n'ai pas trouvé de problème que je ne pouvais pas résoudre en utilisant cvskit.

Pour extraire une ou plusieurs colonnes d'un fichier cvs, vous pouvez utiliser l'utilitaire csvcut qui fait partie de la boîte à outils. Pour extraire la deuxième colonne, utilisez cette commande :

csvcut -c  2 nom_fichier_in.csv > nom_fichier_out.csv

page de référence de csvcut

Si les chaînes de caractères dans le csv sont entre guillemets, ajoutez le caractère de guillemet avec l'option q :

csvcut -q '"' -c 2 nom_fichier_in.csv > nom_fichier_out.csv 

Installez avec pip install csvkit ou sudo apt install csvkit.

5voto

jarno Points 621

Vous pourriez utiliser GNU Awk, voir cet article du guide de l'utilisateur. Comme amélioration à la solution présentée dans l'article (en juin 2015), la commande gawk suivante permet les guillemets doubles à l'intérieur de champs entre guillemets doubles ; un guillemet double est marqué par deux guillemets doubles consécutifs ("") là-bas. De plus, cela permet des champs vides, mais même cela ne peut pas gérer les champs multilignes. L'exemple suivant imprime la 3ème colonne (via c=3) du fichier texte.csv :

#!/bin/bash
gawk -- '
BEGIN{
    FPAT="([^,\"]*)|(\"((\"\")*[^\"]*)*\")"
}
{
    if (substr($c, 1, 1) == "\"") {
        $c = substr($c, 2, length($c) - 2) # Obtient le texte entre les deux guillemets
        gsub("\"\"", "\"", $c)  # Normalise les guillemets doubles
    }
    print $c
}
' c=3 < <(dos2unix 


Remarquez l'utilisation de `dos2unix` pour convertir les sauts de ligne de style DOS possibles (CRLF c'est-à-dire "\r\n") et le codage UTF-16 (avec marque d'ordre des octets) en "\n" et UTF-8 (sans marque d'ordre des octets), respectivement. Les fichiers CSV standard utilisent CRLF comme saut de ligne, voir [Wikipedia](https://en.wikipedia.org/wiki/Comma-separated_values#Standardization).

**Si l'entrée peut contenir des champs multilignes, vous pouvez utiliser le script suivant.** Notez l'utilisation d'une chaîne spéciale pour séparer les enregistrements en sortie (puisque le séparateur de ligne par défaut pourrait être présent dans un enregistrement). Encore une fois, l'exemple suivant imprime la 3ème colonne (via `c=3`) du fichier texte.csv :

    #!/bin/bash
    gawk -- '
    BEGIN{
        RS="\0" # Lire le fichier d'entrée complet comme un enregistrement ;
        # supposer qu'il n'y a pas de caractère nul dans l'entrée.
        FS="" # Supposons que ce paramètre facilite le travail de division interne.
        ORS="\n####\n" # Utiliser un séparateur de sortie spécial pour montrer les bordures d'un enregistrement.
    }
    {
        nof=patsplit($0, a, /([^,"\n]*)|("(("")*[^"]*)*")/, seps)
        field=0;
        for (i=1; i<=nof; i++){
            field++
            if (field==c) {
                if (substr(a[i], 1, 1) == "\"") {
                    a[i] = substr(a[i], 2, length(a[i]) - 2) # Obtient le texte dans 
                    # les deux guillemets.
                    gsub(/""/, "\"", a[i])  # Normalise les guillemets doubles.
                }
                print a[i]
            }
            if (seps[i]!=",") field=0
        }
    }
    ' c=3 < <(dos2unix 

``

Il existe une autre approche au problème. [csvquote](https://github.com/dbro/csvquote) peut produire le contenu d'un fichier CSV modifié pour que les caractères spéciaux dans les champs soient transformés de telle sorte que les outils de traitement du texte Unix habituels puissent être utilisés pour sélectionner certaines colonnes. Par exemple, le code suivant affiche la troisième colonne :

    csvquote textfile.csv | cut -d ',' -f 3 | csvquote -u

`csvquote` peut être utilisé pour traiter des fichiers de taille arbitraire.

`` ```

4voto

exussum Points 6091
csvtool col 2 file.csv 

où 2 est la colonne qui vous intéresse

vous pouvez aussi faire

csvtool col 1,2 file.csv 

pour effectuer des colonnes multiples

3voto

Sav K0 Points 39

Simple solution using awk. Instead of "colNum" put the number of column you need to print.

cat fileName.csv | awk -F ";" '{ print $colNum }'

Traduction en français :

Simple solution using awk. Instead of "colNum" put the number of column you need to print.

cat fileName.csv | awk -F ";" '{ print $colNum }'

1voto

j3h Points 679

Si vous savez que vos données ne seront pas entre guillemets, alors toute solution qui se divise sur , fonctionnera bien (j'ai tendance à utiliser cut -d, -f1 | sed 1d), tout comme n'importe quel outil de manipulation de CSV.

Si vous voulez produire un autre fichier CSV, alors xsv, csvkit, csvtool, ou d'autres outils de manipulation de CSV sont appropriés.

Si vous voulez extraire le contenu d'une seule colonne d'un fichier CSV, désabonnement afin qu'ils puissent être traités par des commandes ultérieures, cette ligne Python fait l'affaire pour les fichiers CSV avec des en-têtes:

python -c 'import csv,sys'$'\n''for row in csv.DictReader(sys.stdin): print(row["message"])'

Le "message" à l'intérieur de la fonction print sélectionne la colonne.

Si le fichier CSV n'a pas d'en-têtes:

python -c 'import csv,sys'$'\n''for row in csv.reader(sys.stdin): print(row[1])'

La bibliothèque CSV de Python prend en charge toutes sortes de dialectes CSV, donc si votre fichier CSV utilise des conventions différentes, il est possible de les prendre en charge avec relativement peu de modifications dans le code.

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