Existe uma robusta ferramenta de linha de comando para processar arquivos csv?

44

Eu trabalho com arquivos CSV e às vezes preciso verificar rapidamente o conteúdo de uma linha ou coluna na linha de comando. Em muitos casos, cut , head , tail e amigos farão o trabalho; no entanto, o corte não pode lidar facilmente com situações como

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

Aqui, a primeira vírgula faz parte do primeiro campo, mas cut -d, -f1 discorda. Antes de escrever uma solução, fiquei me perguntando se alguém sabia de uma boa ferramenta que já existe para esse trabalho. Teria que, no mínimo, ser capaz de manipular o exemplo acima e retornar uma coluna de um arquivo formatado em CSV. Outros recursos desejáveis incluem a capacidade de selecionar colunas com base nos nomes de coluna fornecidos na primeira linha, suporte a outros estilos de cotação e suporte a arquivos separados por tabulações.

Se você não conhece uma ferramenta desse tipo, mas tem sugestões sobre a implementação de tal programa no Bash, no Perl ou no Python, ou em outras linguagens de script comuns, não me importaria com essas sugestões.

    
por Steven D 15.02.2011 / 08:55

17 respostas

34

Você pode usar o módulo csv do Python.

Um exemplo simples:

import csv
reader = csv.reader(open("test.csv", "rb"))
for row in reader:
    for col in row:
        print col
    
por 15.02.2011 / 09:56
35

Provavelmente estou um pouco atrasado, mas há outra ferramenta que vale a pena mencionar: csvkit

link

Tem muitas ferramentas de linha de comando que podem:

  • converter para e de csv de vários formatos (json, sql, xls)
  • cut, grep, sort e outros
  • junte diferentes arquivos csv!
por 15.07.2014 / 19:18
14

Parece um trabalho para Perl com Text::CSV .

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

Consulte a documentação sobre como lidar com nomes de colunas. O separador e o estilo de citação podem ser ajustados com parâmetros para new . Veja também Text::CSV::Separator para adivinhação de separadores.

    
por 15.02.2011 / 09:31
10

Eu encontrei o csvfix, uma ferramenta de linha de comando faz bem o trabalho. Você precisará fazer isso sozinho:

link

Ele faz tudo o que você espera, ordena / seleciona colunas, divide / mescla e muitas não gostaria de gerar inserções SQL a partir de dados CSV e dados CSV diferentes.

    
por 21.09.2011 / 17:17
6

R não é minha linguagem de programação favorita, mas é bom para coisas como essa. Se o seu arquivo csv for

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

Dentro do tipo de interpretador de 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

Em relação às suas outras solicitações, para "a capacidade de selecionar colunas com base nos nomes de coluna fornecidos na primeira linha", consulte

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

Para "suporte a outros estilos de cotação", consulte o argumento quote para read.csv (e funções relacionadas). Para "suporte para arquivos separados por tabulações", consulte o argumento sep para read.csv (configure sep para '\ t').

Para mais informações, consulte a ajuda on-line.

> help(read.csv)
    
por 01.04.2011 / 23:33
6

Eu usei csvtool uma vez e ele me poupou muito tempo e problema. Pode ser chamado a partir do shell.

link

    
por 21.09.2011 / 22:27
6

Se você quiser usar a linha de comando (e não criar um programa inteiro para fazer o trabalho), você gostaria de usar filas , um projeto em que estou trabalhando: é uma interface de linha de comando para dados tabulares, mas também uma biblioteca Python para usar em seus programas. Com a interface de linha de comando, você pode imprimir dados em CSV, XLS, XLSX, HTML ou qualquer outro formato de tabela suportado pela biblioteca com um comando simples:

rows print myfile.csv

Se myfile.csv for assim:

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

Em seguida, as linhas imprimirão o conteúdo de uma forma bonita, assim:

+-------+-------------------------------+-------------+---------+
| 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 |
+-------+-------------------------------+-------------+---------+

Instalando

Se você é um desenvolvedor de Python e já tem pip instalado em sua máquina, basta executar dentro de um virtualenv ou com sudo :

pip install rows

Se você estiver usando o Debian:

sudo apt-get install rows

Outros recursos legais

Convertendo formatos

Você pode converter entre qualquer formato suportado:

rows convert myfile.xlsx myfile.csv

Consultando

Sim, você pode usar o SQL em um arquivo CSV:

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

A conversão da saída da consulta para um arquivo em vez de stdout também é possível usando o parâmetro --output .

Como uma biblioteca Python

Você também pode em seus programas em Python:

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

Espero que você goste!

    
por 05.08.2016 / 03:16
4

Você também pode experimentar alguma mágica awk . No entanto, não sou um bom usuário awk e não posso confirmar se isso funcionaria corretamente e como fazê-lo.

    
por 15.02.2011 / 13:30
3

Dê uma olhada também em GNU Recutils e crush-tools .

(via link )

    
por 21.11.2011 / 16:42
2

Para usar o python a partir da linha de comando, você pode verificar o pythonpy ( link ):

$ echo $'a,b,c\nd,e,f' | py '[x[1] for x in csv.reader(sys.stdin)']
b
e
    
por 27.09.2014 / 06:37
2

tente "csvtool" este pacote é útil ferramenta de linha de comando para lidar com arquivos CSV

    
por 03.09.2015 / 08:53
2
O

cissy também fará o processamento csv da linha de comando. Está escrito em C (pequeno / leve) com pacotes rpm e deb disponíveis para a maioria das distros.

Usando o exemplo:

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
    
por 18.09.2015 / 15:22
2
O

Miller é outra boa ferramenta para manipular dados baseados em nome, incluindo CSV (com cabeçalhos). Para extrair a primeira coluna de um arquivo CSV, sem se importar com seu nome, você faria algo como

printf '"first,column",second,third\n1,2,3\n' |
  mlr --csv --implicit-csv-header --headerless-csv-output cut -f 1
    
por 12.09.2017 / 13:33
1

Há também uma biblioteca Curry para leitura / gravação de arquivos no formato CSV: CSV .

    
por 20.04.2011 / 23:26
1

O repositório do github Ferramentas de texto estruturado tem uma lista útil de ferramentas de linha de comando do Linux relevantes. Em particular, a seção Valores Separados por Delimitadores lista várias ferramentas compatíveis com CSV que suportam diretamente as operações solicitadas.

    
por 12.09.2017 / 14:12
0

Uma solução 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
    
por 12.08.2014 / 07:23
0

Eu recomendaria xsv - Um rápido kit de ferramentas de linha de comando CSV escrito em Rust ( Github ) .

Escrito por autor do Ripgrep .

Apresentado em Como fizemos nosso processamento de CSV 142 vezes mais rápido ( thread do Reddit ).

    
por 05.08.2018 / 21:24