Dê uma olhada no fsql (Perl) ou csvkit (Python). Ambos têm vários problemas e limitações, mas geralmente são bons para dados "pequenos". E, claro, você sempre pode recorrer a um banco de dados apropriado quando não é suficiente.
Eu estava procurando uma maneira de percorrer arquivos CSV como tabelas de banco de dados relacional.
Eu fiz algumas pesquisas, pois nada achei adequado à minha lista de requisitos em sua totalidade. Eu encontrei várias opções parcialmente boas, a saber:
É possível, e muito simples, percorrer e executar algumas operações semelhantes a banco de dados em um arquivo csv / text único (somas de coluna, médias, min, max, subconjuntos, etc), mas não em dois arquivos, com alguma conexão entre eles. Também é possível importar os arquivos para um banco de dados temporário para consulta, e eu fiz isso, embora não seja tão prático quanto gostaria.
TL; DR - Eu basicamente gostaria de uma maneira conveniente de fazer junções SQL rápidas e sujas em arquivos csv. Não estou procurando um RDBMS baseado em texto completo, mas apenas uma maneira mais agradável de fazer algumas análises sobre extrações de RDBMS csv.
exemplo:
sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'
Este parece ser um problema bastante interessante que eu poderia dedicar algum tempo, mas gostaria de saber se já existe.
O que você quer é o comando join
, que é especificado por POSIX .
Aqui está o seu comando pseudocode de exemplo:
sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'
Aqui está um comando de trabalho real usando join
que é equivalente:
join -t, tbl1.csv tbl2.csv
Se os dois arquivos tiverem apenas dois campos separados por vírgula, esse comando join
é exatamente o que você representa no pseudocódigo.
Se eles tiverem mais campos, mas você só quiser até o segundo campo de cada arquivo, ainda entrando no primeiro campo, você usaria:
join -t, -o 0,1.2,2.2 tbl1.csv tbl2.csv
Se você quiser participar de um campo diferente, também há sinalizadores para isso.
Não é um RDBMS completo; por exemplo, você está limitado a apenas dois arquivos e um único campo de junção. Mas pelo que você pediu:
TL;DR - I basically would like a convenient way to do quick and dirty sql joins on csv files. Not looking for a full fledged text based RDBMS, but just a nicer way to do some analysis on csv RDBMS extracts.
Ele se encaixa perfeitamente na conta .
Você também deve verificar comm
, também especificado por POSIX , que é para linhas de impressão comuns a dois arquivos (ou apenas presentes em um ou outro deles, ou coisas semelhantes).
Observe também que join
e comm
podem operar na entrada padrão usando -
como nome de arquivo.
Se você quer o equivalente a um comando SQL "count ()" com uma cláusula "group by", é só pegar a coluna que você quer (qual join
irá ordenar usando o campo join, ou você pode se classificar diretamente de um arquivo) e canalizá-lo através de uniq -c
.
Entre Awk , join , uniq , comm e classificar , você pode fazer algumas coisas muito extravagantes com CSVs. E tudo isso compatível com POSIX.
Apache Drill pode consultar diretamente os arquivos CSV e JSON, além de se unir a eles.
Você só precisa definir a localização dos arquivos e ajustar as configurações com base na extensão do arquivo (por exemplo, se deseja usar a primeira linha como cabeçalho ou não) na primeira vez.
Então é como se você estivesse usando o cliente mysql
, mas as tabelas são os arquivos reais no disco
$ ./bin/drill-embedded
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0
Nov 07, 2017 7:05:52 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.8 2014-04-29 01:25:26...
apache drill 1.11.0
"drill baby drill"
0: jdbc:drill:zk=local> SELECT ix.field1, o.field2, o.field3
. . . . . . . . . . . > FROM dfs.myfolder.'file1.tsv' ix
. . . . . . . . . . . > LEFT JOIN dfs.myfolder.'file2.tsv' o ON (o.field=ix.field)
. . . . . . . . . . . > LIMIT 10;
+-------------+-------------+---------------+
| field1 | field2 | field3 |
+-------------+-------------+---------------+
...redacted...
+-------------+-------------+---------------+
10 rows selected (0.656 seconds)
0: jdbc:drill:zk=local>