Como analisar dados CSV no Bash
Publicados: 2022-09-16Os arquivos de valores separados por vírgula (CSV) são um dos formatos mais comuns para dados exportados. No Linux, podemos ler arquivos CSV usando comandos Bash. Mas pode ficar muito complicado, muito rapidamente. Nós vamos dar uma mão.
O que é um arquivo CSV?
Um arquivo de valores separados por vírgula é um arquivo de texto que contém dados tabulados. CSV é um tipo de dados delimitados. Como o nome sugere, uma vírgula “ ,
” é usada para separar cada campo de dados – ou valor – de seus vizinhos.
CSV está em toda parte. Se um aplicativo tiver funções de importação e exportação, quase sempre oferecerá suporte a CSV. Os arquivos CSV são legíveis por humanos. Você pode olhar dentro deles com menos, abri-los em qualquer editor de texto e movê-los de programa para programa. Por exemplo, você pode exportar os dados de um banco de dados SQLite e abri-lo no LibreOffice Calc.
No entanto, mesmo CSV pode se tornar complicado. Quer ter uma vírgula em um campo de dados? Esse campo precisa ter aspas “ "
”. Para incluir aspas em um campo, cada aspas precisa ser inserida duas vezes.
Claro, se você estiver trabalhando com CSV gerado por um programa ou script que você escreveu, o formato CSV provavelmente será simples e direto. Se você for forçado a trabalhar com formatos CSV mais complexos, com Linux sendo Linux, existem soluções que podemos usar para isso também.
Alguns dados de amostra
Você pode gerar facilmente alguns dados CSV de amostra, usando sites como o Online Data Generator. Você pode definir os campos que deseja e escolher quantas linhas de dados deseja. Seus dados são gerados usando valores fictícios realistas e baixados para o seu computador.
Criamos um arquivo contendo 50 linhas de informações fictícias de funcionários:
- id : Um valor inteiro único e simples.
- firstname : O primeiro nome da pessoa.
- lastname : O sobrenome da pessoa.
- job-title : o cargo da pessoa.
- email-address : o endereço de email da pessoa.
- branch : A filial da empresa em que trabalham.
- state : o estado em que a filial está localizada.
Alguns arquivos CSV têm uma linha de cabeçalho que lista os nomes dos campos. Nosso arquivo de amostra tem um. Aqui está o topo do nosso arquivo:
A primeira linha contém os nomes dos campos como valores separados por vírgulas.
Analisando dados do arquivo CSV
Vamos escrever um script que irá ler o arquivo CSV e extrair os campos de cada registro. Copie este script em um editor e salve-o em um arquivo chamado “field.sh”.
#! /bin/bash while IFS="," read -r id firstname sobrenome jobtitle email branch state Faz echo "ID do registro: $id" echo "Nome: $nome" echo "Sobrenome: $sobrenome" echo "Título do trabalho: $jobtitle" echo "Adicionar email: $email" echo "Ramo: $ramo" echo "Estado: $estado" eco "" feito < <(cauda -n +2 amostra.csv)
Há bastante coisa em nosso pequeno script. Vamos decompô-lo.
Estamos usando um loop while
. Enquanto a condição do loop while
for verdadeira, o corpo do loop while
será executado. O corpo do loop é bastante simples. Uma coleção de instruções echo
é usada para imprimir os valores de algumas variáveis na janela do terminal.
A condição do laço while
é mais interessante que o corpo do laço. Especificamos que uma vírgula deve ser usada como separador de campo interno, com a instrução IFS=","
. O IFS é uma variável de ambiente. O comando de read
refere-se ao seu valor ao analisar sequências de texto.
Estamos usando a opção -r
(reter barras invertidas) do comando read
para ignorar quaisquer barras invertidas que possam estar nos dados. Eles serão tratados como personagens normais.
O texto que o comando de read
analisa é armazenado em um conjunto de variáveis com o nome dos campos CSV. Eles poderiam facilmente ter sido nomeados field1, field1, field2, ... field7
, mas nomes significativos tornam a vida mais fácil.
Os dados são obtidos como saída do comando tail
. Estamos usando tail
porque nos dá uma maneira simples de pular a linha de cabeçalho do arquivo CSV. A opção -n +2
(número da linha) diz ao tail
para começar a ler na linha número dois.
A construção <(...)
é chamada de substituição de processo. Isso faz com que o Bash aceite a saída de um processo como se estivesse vindo de um descritor de arquivo. Isso é então redirecionado para o loop while
, fornecendo o texto que o comando de read
analisará.
Torne o script executável usando o comando chmod
. Você precisará fazer isso toda vez que copiar um script deste artigo. Substitua o nome do script apropriado em cada caso.
chmod +x campo.sh
Quando executamos o script, os registros são divididos corretamente em seus campos constituintes, com cada campo armazenado em uma variável diferente.
./field.sh
Cada registro é impresso como um conjunto de campos.
Selecionando campos
Talvez não queiramos ou precisemos recuperar todos os campos. Podemos obter uma seleção de campos incorporando o comando cut
.
Esse script é chamado de “select.sh”.
#!/bin/bash while IFS="," leia -r id jobtitle branch state Faz echo "ID do registro: $id" echo "Título do trabalho: $jobtitle" echo "Ramo: $ramo" echo "Estado: $estado" eco "" feito < <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)
Adicionamos o comando cut
na cláusula de substituição do processo. Estamos usando a opção -d
(delimitador) para dizer ao cut
para usar vírgulas “ ,
” como delimitador. A opção -f
(campo) diz ao cut
que queremos os campos um, quatro, seis e sete. Esses quatro campos são lidos em quatro variáveis, que são impressas no corpo do loop while
.
Isso é o que obtemos quando executamos o script.
./select.sh
Ao adicionar o comando cut
, podemos selecionar os campos que queremos e ignorar os que não queremos.
Até agora tudo bem. Mas…
Se o CSV com o qual você lida não é complicado, sem vírgulas ou aspas nos dados de campo, o que abordamos provavelmente atenderá às suas necessidades de análise de CSV. Para mostrar os problemas que podemos encontrar, modificamos uma pequena amostra dos dados para ficar assim.
id,nome,sobrenome,cargo-título,endereço de e-mail,filial,estado 1,Rosalyn,Brennan,"Steward, Senior",[email protected],Minneapolis,Maryland 2,Danny,Redden,"Analista ""Budget""",[email protected],Venice,North Carolina 3, Lexi, Roscoe, Farmacêutico,, Irlington, Vermont
- O registro um tem uma vírgula no campo
job-title
, então o campo precisa ser colocado entre aspas. - O registro dois tem uma palavra envolta em dois conjuntos de aspas no campo
jobs-title
. - O registro três não tem dados no campo
email-address
.
Esses dados foram salvos como "sample2.csv". Modifique seu script “field.sh” para chamar o “sample2.csv” e salve-o como “field2.sh”.
#! /bin/bash while IFS="," read -r id firstname sobrenome jobtitle email branch state Faz echo "ID do registro: $id" echo "Nome: $nome" echo "Sobrenome: $sobrenome" echo "Título do trabalho: $jobtitle" echo "Adicionar email: $email" echo "Ramo: $ramo" echo "Estado: $estado" eco "" feito < <(cauda -n +2 amostra2.csv)
Quando executamos este script, podemos ver rachaduras aparecendo em nossos analisadores CSV simples.
./field2.sh
O primeiro registro divide o campo de cargo em dois campos, tratando a segunda parte como o endereço de e-mail. Cada campo depois disso é deslocado um lugar para a direita. O último campo contém os valores da branch
e do state
.
O segundo registro mantém todas as aspas. Deve ter apenas um único par de aspas ao redor da palavra "Orçamento".
O terceiro registro realmente trata o campo ausente como deveria. O endereço de e-mail está faltando, mas todo o resto está como deveria estar.
Contraintuitivamente, para um formato de dados simples, é muito difícil escrever um analisador CSV de caso geral robusto. Ferramentas como o awk
permitem que você se aproxime, mas sempre há casos extremos e exceções que escapam.
Tentar escrever um analisador CSV infalível provavelmente não é o melhor caminho a seguir. Uma abordagem alternativa - especialmente se você estiver trabalhando com algum tipo de prazo - emprega duas estratégias diferentes.
Uma é usar uma ferramenta projetada para manipular e extrair seus dados. A segunda é higienizar seus dados e substituir cenários de problemas, como vírgulas e aspas incorporadas. Seus analisadores Bash simples podem então lidar com o CSV amigável ao Bash.
O kit de ferramentas csvkit
O kit de ferramentas CSV csvkit
é uma coleção de utilitários criados expressamente para ajudar a trabalhar com arquivos CSV. Você precisará instalá-lo em seu computador.
Para instalá-lo no Ubuntu, use este comando:
sudo apt instalar csvkit
Para instalá-lo no Fedora, você precisa digitar:
sudo dnf install python3-csvkit
No Manjaro o comando é:
sudo pacman -S csvkit
Se passarmos o nome de um arquivo CSV para ele, o utilitário csvlook
exibe uma tabela mostrando o conteúdo de cada campo. O conteúdo do campo é exibido para mostrar o que o conteúdo do campo representa, não como está armazenado no arquivo CSV.
Vamos tentar csvlook
com nosso arquivo problemático “sample2.csv”.
csvlook sample2.csv
Todos os campos são exibidos corretamente. Isso prova que o problema não é o CSV. O problema é que nossos scripts são muito simplistas para interpretar o CSV corretamente.
Para selecionar colunas específicas, use o comando csvcut
. A opção -c
(coluna) pode ser usada com nomes de campos ou números de colunas ou uma combinação de ambos.
Suponha que precisamos extrair os nomes e sobrenomes, cargos e endereços de e-mail de cada registro, mas queremos que a ordem dos nomes seja "sobrenome, nome". Tudo o que precisamos fazer é colocar os nomes ou números dos campos na ordem que queremos.
Esses três comandos são todos equivalentes.
csvcut -c sobrenome, nome, cargo-título, endereço de e-mail amostra2.csv
csvcut -c sobrenome, nome, 4,5 amostra2.csv
csvcut -c 3,2,4,5 amostra2.csv
Podemos adicionar o comando csvsort
para classificar a saída por um campo. Estamos usando a opção -c
(coluna) para especificar a coluna pela qual classificar e a opção -r
(reversa) para classificar em ordem decrescente.
csvcut -c 3,2,4,5 amostra2.csv | csvsort -c 1 -r
Para deixar a saída mais bonita podemos alimentá-la através csvlook
.
csvcut -c 3,2,4,5 amostra2.csv | csvsort -c 1 -r | csvlook
Um toque legal é que, mesmo que os registros sejam classificados, a linha de cabeçalho com os nomes dos campos é mantida como a primeira linha. Quando estivermos satisfeitos por termos os dados do jeito que queremos, podemos remover o csvlook
da cadeia de comando e criar um novo arquivo CSV redirecionando a saída para um arquivo.
Adicionamos mais dados ao “sample2.file”, removemos o comando csvsort
e criamos um novo arquivo chamado “sample3.csv”.
csvcut -c 3,2,4,5 amostra2.csv > amostra3.csv
Uma maneira segura de higienizar dados CSV
Se você abrir um arquivo CSV no LibreOffice Calc, cada campo será colocado em uma célula. Você pode usar a função localizar e substituir para procurar vírgulas. Você pode substituí-los por “nada” para que desapareçam, ou por um caractere que não afete a análise do CSV, como um ponto e vírgula “ ;
" por exemplo.
Você não verá as aspas nos campos entre aspas. As únicas aspas que você verá são as aspas incorporadas nos dados do campo. Estes são mostrados como aspas simples. Localizar e substituí-los por um único apóstrofo “ '
” substituirá as aspas duplas no arquivo CSV.
Fazer a localização e substituição em um aplicativo como o LibreOffice Calc significa que você não pode excluir acidentalmente nenhuma das vírgulas separadoras de campo, nem excluir as aspas em torno dos campos entre aspas. Você só alterará os valores de dados dos campos.
Alteramos todas as vírgulas em campos com ponto e vírgula e todas as aspas incorporadas com apóstrofos e salvamos nossas alterações.
Em seguida, criamos um script chamado “field3.sh” para analisar “sample3.csv”.
#! /bin/bash while IFS="," leia -r sobrenome primeiro nome e-mail do cargo Faz echo "Sobrenome: $sobrenome" echo "Nome: $nome" echo "Título do trabalho: $jobtitle" echo "Adicionar email: $email" eco "" feito < <(cauda -n +2 amostra3.csv)
Vamos ver o que obtemos quando o executamos.
./field3.sh
Nosso analisador simples agora pode lidar com nossos registros anteriormente problemáticos.
Você verá muito CSV
CSV é sem dúvida a coisa mais próxima de uma língua comum para dados de aplicativos. A maioria dos aplicativos que lidam com algum tipo de dados oferece suporte à importação e exportação de CSV. Saber como lidar com o CSV — de maneira realista e prática — o ajudará muito.
RELACIONADO: 9 exemplos de script Bash para você começar no Linux