web-dev-qa-db-fra.com

Existe-t-il un outil de ligne de commande robuste pour le traitement des fichiers CSV?

Je travaille avec des fichiers CSV et je dois parfois vérifier rapidement le contenu d'une ligne ou d'une colonne de la ligne de commande. Dans de nombreux cas cut, head, tail et amis feront le travail; Cependant, la réduction ne peut pas facilement traiter des situations telles que

"this, is the first entry", this is the second, 34.5

Ici, la première virgule fait partie du premier domaine, mais cut -d, -f1 en désaccord. Avant d'écrire une solution moi-même, je me demandais si quelqu'un connaissait un bon outil qui existe déjà pour ce travail. Il faudrait à tout le moins pouvoir gérer l'exemple ci-dessus et renvoyer une colonne à partir d'un fichier formaté CSV. Parmi les autres caractéristiques souhaitables, citons la possibilité de sélectionner des colonnes basées sur les noms de colonne indiqués dans la première ligne, prenant en charge les autres styles de citation et prendre en charge les fichiers séparés par tabulation.

Si vous ne connaissez pas un tel outil mais que vous avez des suggestions concernant la mise en œuvre d'un tel programme dans Bash, Perl ou Python, ou d'autres langages de script communs, cela ne vous dérangerait pas de telles suggestions.

47
Steven D

Vous pouvez utiliser Python csv module.

Un exemple simple:

import csv
reader = csv.reader(open("test.csv", "r"))
for row in reader:
    for col in row:
        print col
38
dogbane

Je suis probablement un peu trop tard, mais un autre outil mérite d'être mentionné: CSVKIT

http://csvkit.readthedocs.org/

Il a beaucoup d'outils de ligne de commande qui peuvent:

  • reformatant les fichiers CSV,
  • convertir et à partir de CSV de divers formats (JSON, SQL, XLS),
  • l'équivalent de cut, grep, sort et autres, mais CSV -
  • rejoignez différents fichiers CSV,
  • do General SQL requête sur les données des fichiers CSV.
40
romaia

Cela ressemble à un travail pour Perl avec Text::CSV .

Perl -MText::CSV -pe '
    BEGIN {$csv = Text::CSV->new();}
    $csv->parse($_) or die;
    @fields = $csv->fields();
    print @fields[1,3];
'

Voir la documentation sur la façon de gérer les noms de colonne. Le séparateur et le style de citation peuvent être réglés avec des paramètres sur new. Voir également Text::CSV::Separator pour la supposition de séparation.

J'ai trouvé CSVFIX, un outil de ligne de commande fait bien le travail. Vous devrez le faire vous-même cependant:

http://neilb.bitbucket.org/csvfix

Toutes les choses que vous attendez, commander/sélectionner des colonnes, Split/Fusion et beaucoup vous souhaiteriez générer des inserts SQL à partir de données CSV et diffèrent des données CSV.

10
Daniel Burke

Si vous souhaitez utiliser la ligne de commande (et ne créez pas un programme entier pour faire le travail), vous souhaitez utiliser lignes , un projet que je travaille sur: c'est une commande Interface de ligne sur les données tabulaires mais aussi a Python Library à utiliser dans vos programmes. Avec l'interface de ligne de commande, vous pouvez prettoir toutes les données dans CSV, XLS, XLSX, HTML ou tout autre tabulaire format pris en charge par la bibliothèque avec une commande simple:

rows print myfile.csv

Si myfile.csv est comme ça:

state,city,inhabitants,area
RJ,Angra dos Reis,169511,825.09
RJ,Aperibé,10213,94.64
RJ,Araruama,112008,638.02
RJ,Areal,11423,110.92
RJ,Armação dos Búzios,27560,70.28

Alors lignes Imprimer le contenu d'une belle façon, comme ceci:

+-------+-------------------------------+-------------+---------+
| state |              city             | inhabitants |   area  |
+-------+-------------------------------+-------------+---------+
|    RJ |                Angra dos Reis |      169511 |  825.09 |
|    RJ |                       Aperibé |       10213 |   94.64 |
|    RJ |                      Araruama |      112008 |  638.02 |
|    RJ |                         Areal |       11423 |  110.92 |
|    RJ |            Armação dos Búzios |       27560 |   70.28 |
+-------+-------------------------------+-------------+---------+

Installation

Si vous êtes Python Developer et avez déjà pip installé sur votre machine, il suffit d'exécuter à l'intérieur d'un virtualenv ou de Sudo:

pip install rows

Si vous utilisez Debian:

Sudo apt-get install rows

Autres caractéristiques cool

Convertir des formats

Vous pouvez convertir entre tout format pris en charge:

rows convert myfile.xlsx myfile.csv

Interrogation

Oui, vous pouvez utiliser SQL dans un fichier CSV:

$ rows query 'SELECT city, area FROM table1 WHERE inhabitants > 100000' myfile.csv
+----------------+--------+
|      city      |  area  |
+----------------+--------+
| Angra dos Reis | 825.09 |
|       Araruama | 638.02 |
+----------------+--------+

Conversion de la sortie de la requête en un fichier au lieu de stdout est également possible en utilisant le --output Paramètre.

Comme un Python Bibliothèque

Vous pouvez vous dans votre Python programmes aussi:

import rows
table = rows.import_from_csv('myfile.csv')
rows.export_to_txt(table, 'myfile.txt')
# `myfile.txt` will have same content as `rows print` output

Je espère que vous l'apprécierez!

8
Álvaro Justen

J'ai utilisé CSVTool une fois et cela m'a sauvé beaucoup de temps et de problèmes. Appelable de la coquille.

http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=447

6
nat

R Ce n'est pas mon langage de programmation préféré, mais c'est bon pour des choses comme ça. Si votre fichier CSV est

***********
foo.csv
***********
 col1, col2, col3
"this, is the first entry", this is the second, 34.5
'some more', "messed up", stuff

À l'intérieur du type interprète r

> x=read.csv("foo.csv", header=FALSE)

> x
                     col1                col2   col3
1 this, is the first entry  this is the second   34.5
2              'some more'           messed up  stuff
> x[1]  # first col
                      col1
1 this, is the first entry
2              'some more'
> x[1,] # first row
                      col1                col2  col3
1 this, is the first entry  this is the second  34.5

En ce qui concerne vos autres demandes, pour "la possibilité de sélectionner des colonnes basées sur les noms de colonne donnés dans la première ligne" Voir

> x["col1"]
                      col1
1 this, is the first entry
2              'some more'

Pour "Support pour d'autres styles de citation", voir l'argument quote argument à lire.csv (et fonctions associées). Pour "Support pour les fichiers séparés par tabulation", voir l'argument sep _ argument à lire.csv (définir sep à '\ t').

Pour plus d'informations, voir l'aide en ligne.

> help(read.csv)
6
Faheem Mitha

Miller est un autre outil intéressant pour manipuler des données à base de noms, y compris CSV (avec des en-têtes). Extraire la première colonne d'un fichier CSV, sans se soucier de son nom, vous feriez quelque chose comme

printf '"first,column",second,third\n1,2,3\n' |
  mlr --csv --implicit-csv-header --headerless-csv-output cut -f 1
4
Stephen Kitt

Ou, vous pouvez essayer certains awk magie. Comment, je ne suis pas un bon utilisateur AWK et je ne peux pas confirmer que cela fonctionnerait correctement et comment le faire.

3
rvs

CISSY fera également le traitement CSV de ligne de commande. Il est écrit en C (petit/léger) avec des emballages RPM et Deb disponibles pour la plupart des distributions.

En utilisant l'exemple:

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 1
"this, is the first entry"

ou

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2
 this is the second

ou

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2-
 this is the second, 34.5
3
slass100

Je recommanderais XSV - une boîte à outils de ligne de commande de CSV rapide écrit dans la rouille ( GitHub ).

Écrit par RIPGREP Auteur.

En vedette dans Comment nous avons effectué notre traitement de CSV 142x plus rapidement ( filetage Reddit ).

3
Nicolas Girard

essayez "CSVTool" ce paquet C'est un outil de ligne de commande pratique pour la gestion des fichiers CSV

2
dominic

Pour utiliser python de la ligne de commande, vous pouvez consulter Pythonpy ( https://github.com/russell91/pythonpy ):

$ echo $'a,b,c\nd,e,f' | py '[x[1] for x in csv.reader(sys.stdin)']
b
e
2
RussellStewart

L'un des meilleurs outils est Miller ( http://johnkerl.org/miller/doc/index.html ). C'est comme AWK, SED, Couper, rejoindre et trier les données indexées par nom, telles que CSV, TSV et JSON Tabular.

Par exemple

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --icsv --implicit-csv-header cat

vous donne

1=this, is the first entry,2= this is the second,3= 34.5

Si vous voulez un TSV

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --c2t --implicit-csv-header cat

vous donne (il est possible de retirer l'en-tête)

1       2       3
this, is the first entry         this is the second      34.5

Si vous voulez première et troisième colonne, changez de commande

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --csv --implicit-csv-header --headerless-csv-output cut -o -f 3,1

vous donne

 34.5,"this, is the first entry"
1
aborruso

Les répétitions GITUB Texte structuré dispose d'une liste utile d'outils de ligne de commande Linux pertinents. En particulier, la section Valeurs séparées par Délimiter répertorie plusieurs outils capables de CSV qui prennent en charge directement les opérations demandées.

1
JonDeg

Si vous voulez un outil visuel/interactif dans le terminal, je recommande de tout coeur Visidata.

enter image description here

Il dispose de tables de fréquences (indiquées ci-dessus), de pivotement, de fusion, de diffression, de filtrage/calcul à l'aide de Python, etc.

Vous pouvez transmettre des fichiers csv comme si

vd hello.csv

Il existe des options spécifiques à CSV: --csv-dialect, --csv-delimiter, --csv-quotechar, et --csv-skipinitialspace Pour la manipulation précise des fichiers CSV.

1
DameDebugger

Il y a aussi un curry Bibliothèque de fichiers de lecture/écriture au format CSV: [~ # ~ ~] CSV [~ # ~] .

Une solution AWK

awk -vq='"' '
func csv2del(n) {
  for(i=n; i<=c; i++)
    {if(i%2 == 1) gsub(/,/, OFS, a[i])
    else a[i] = (q a[i] q)
    out = (out) ? out a[i] : a[i]}
  return out}
{c=split($0, a, q); out=X;
  if(a[1]) $0=csv2del(1)
  else $0=csv2del(2)}1' OFS='|' file
0
Srini