Como analisar dados CSV no Bash

Ícone de arquivo com um banner verde mostrando a extensão CSV.

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 ajudar.

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 todo lugar. 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 um programa para outro. Por exemplo, você pode exportar os dados de um banco de dados SQLite e abri-los no LibreOffice Calc .

No entanto, mesmo o CSV pode se tornar complicado. Quer colocar uma vírgula em um campo de dados? Esse campo precisa ter aspas “

 " 

“envolvido. Para incluir aspas em um campo, cada aspa precisa ser inserida duas vezes.

Obviamente, 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çado a trabalhar com formatos CSV mais complexos, sendo o Linux o 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.
  • sobrenome : o sobrenome da pessoa.
  • cargo-título : o cargo da pessoa.
  • email-address : O endereço de email da pessoa.
  • filial : A filial da empresa em que trabalham.
  • estado : o estado em que a filial está localizada.

Alguns arquivos CSV possuem uma linha de cabeçalho que lista os nomes dos campos. Nosso arquivo de amostra tem um. Aqui está o topo do nosso arquivo:

O arquivo CSV de amostra

A primeira linha contém os nomes dos campos como valores separados por vírgula.

Analisando dados do arquivo CSV

Vamos escrever um script que irá ler o arquivo CSV e extrair os campos de cada registro. Copie esse script em um editor e salve-o em um arquivo chamado “field.sh”.

#! /bin/bash

while IFS="," read -r id nome sobrenome cargo cargo e-mail estado da filial

fazer

  echo "ID do registro: $id"

  echo "Nome: $nome"

  echo "Sobrenome: $sobrenome"

  echo "Cargo: $jobtitle"

  echo "Adicionar e-mail: $email"

  echo "Filial: $filial"

  echo "Estado: $estado"

  eco ""

feito < <(cauda -n +2 amostra.csv)

Há bastante coisa em nosso pequeno roteiro. Vamos decompô-lo.

Recomendado:  Trilhas sonoras de videogame são ótimas músicas de fundo para foco

Estamos usando um whileloop. Contanto que a whilecondição do loop seja verdadeira, o corpo do whileloop será executado. O corpo do loop é bastante simples. Uma coleção de echoinstruções é usada para imprimir os valores de algumas variáveis ​​na janela do terminal.

A whilecondição do loop é mais interessante que o corpo do loop. Especificamos que uma vírgula deve ser usada como separador de campo interno, com a IFS=","instrução. O IFS é uma variável de ambiente. O readcomando refere-se ao seu valor ao analisar sequências de texto.

Estamos usando a opção readdo comando -r(reter barras invertidas) para ignorar quaisquer barras invertidas que possam estar nos dados. Eles serão tratados como personagens normais.

O texto que o readcomando analisa é armazenado em um conjunto de variáveis ​​nomeadas após os campos CSV. Eles poderiam facilmente ter sido nomeados field1, field2, ... field7, mas nomes significativos tornam a vida mais fácil.

Os dados são obtidos como saída do tailcomando . Estamos usando tailporque nos oferece uma maneira simples de pular a linha de cabeçalho do arquivo CSV. A -n +2opção (número da linha) indica tailpara 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 viesse de um descritor de arquivo. Isso é então redirecionado para o whileloop, fornecendo o texto que o readcomando irá analisar.

Torne o script executável usando o chmodcomando . Você precisará fazer isso sempre que copiar um script deste artigo. Substitua o nome do script apropriado em cada caso.

chmod +x campo.sh

Tornando um script executável com chmod

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

O arquivo CSV analisado pelo script 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 cutcomando .

Este script é chamado de “select.sh”.

#!/bin/bash

while IFS="," read -r id jobtitle branch state

fazer

  echo "ID do registro: $id"

  echo "Cargo: $jobtitle"

  echo "Filial: $filial"

  echo "Estado: $estado"

  eco ""

feito < <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)

Adicionamos o cutcomando à cláusula de substituição do processo. Estamos usando a -dopção (delimitador) para dizer cutpara usar vírgulas ” ,” como delimitador. A -fopção (campo) informa cutque 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 whileloop.

Isso é o que obtemos quando executamos o script.

./select.sh

Analisando o arquivo CSV com field.sh para extrair uma seleção específica de campos

Ao adicionar o cutcomando, podemos selecionar os campos que queremos e ignorar aqueles que não queremos.

Até agora tudo bem. Mas…

Se o CSV com o qual você lida for simples, 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.

Recomendado:  O melhor da CES 2020: todas as melhores coisas que vimos este ano

id,nome,sobrenome,cargo,endereço de e-mail,filial,estado

1,Rosalyn,Brennan,"Administrador, Sênior",Rosalyn_Brennan4351@mafthy.com,Minneapolis,Maryland

2,Danny,Redden,"Analista ""Orçamento""",Danny_Redden1443@brety.org,Veneza,Carolina do Norte

3, Lexi, Roscoe, Farmacêutico, Irlington, Vermont

  • O registro um possui uma vírgula no job-titlecampo, portanto o campo precisa ser colocado entre aspas.
  • O registro dois tem uma palavra colocada entre dois conjuntos de aspas no jobs-titlecampo.
  • O registro três não possui dados em email-addresscampo.

Esses dados foram salvos como “sample2.csv”. Modifique seu script “field.sh” para chamar “sample2.csv” e salve-o como “field2.sh”.

#! /bin/bash

while IFS="," read -r id nome sobrenome cargo cargo e-mail estado da filial

fazer

  echo "ID do registro: $id"

  echo "Nome: $nome"

  echo "Sobrenome: $sobrenome"

  echo "Cargo: $jobtitle"

  echo "Adicionar e-mail: $email"

  echo "Filial: $filial"

  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

Executando o field2.sh

O primeiro registro divide o campo cargo em dois campos, tratando a segunda parte como o endereço de e-mail. Cada campo depois disso é deslocado uma posição para a direita. O último campo contém os valores branche state.

Um registro com um campo dividido em dois campos

O segundo registro mantém todas as aspas. Deve ter apenas um par de aspas ao redor da palavra “Orçamento”.

Um registro com aspas mal tratadas

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.

Um registro com um campo ausente, que é tratado corretamente

Contraintuitivamente, para um formato de dados simples, é muito difícil escrever um analisador CSV robusto de caso geral. Ferramentas como awkpermitem que você chegue perto, 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 delas é usar uma ferramenta projetada especificamente para manipular e extrair seus dados. A segunda é limpar seus dados e substituir cenários problemáticos, como vírgulas e aspas incorporadas. Seus analisadores Bash simples podem então lidar com o CSV compatível com 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

Instalando csvkit no Ubuntu

Para instalá-lo no Fedora, você precisa digitar:

sudo dnf instalar python3-csvkit

Instalando csvkit no Fedora

No Manjaro o comando é:

sudo pacman -S csvkit

Instalando csvkit no Manjaro

Se lhe passarmos o nome de um arquivo CSV, o csvlook utilitário 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, e não como está armazenado no arquivo CSV.

Vamos tentar csvlookcom nosso arquivo “sample2.csv” problemático.

csvlook amostra2.csv

CSV problemático analisado corretamente pelo csvlook

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.

Recomendado:  Como desinstalar um aplicativo iOS que você não consegue encontrar na tela inicial

Para selecionar colunas específicas, use o csvcutcomando. A -copção (coluna) pode ser usada com nomes de campos ou números de colunas, ou uma combinação de ambos.

Suponha que precisamos extrair o nome e o sobrenome, os cargos e os 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 desejamos.

Esses três comandos são todos equivalentes.

csvcut -c sobrenome,nome,cargo,endereço de e-mail sample2.csv

csvcut -c sobrenome,nome,4,5 sample2.csv

csvcut -c 3,2,4,5 amostra2.csv

Selecionando campos em uma ordem preferencial com csvcut

Podemos adicionar o csvsortcomando para classificar a saída por um campo. Estamos usando a -copção (coluna) para especificar a coluna pela qual classificar e a -ropção (reversa) para classificar em ordem decrescente.

csvcut -c 3,2,4,5 amostra2.csv | csvsort -c 1 -r

Selecionando campos e classificando-os por uma única coluna

Para tornar a saída mais bonita, podemos alimentá-la csvlook.

csvcut -c 3,2,4,5 amostra2.csv | csvsort -c 1 -r | csvlook

Usando csvlook para imprimir a seleção ordenada de campos

Um toque legal é que, mesmo que os registros sejam classificados, a linha do cabeçalho com os nomes dos campos é mantida como a primeira linha. Quando estivermos satisfeitos, temos os dados da maneira que desejamos, podemos removê-los csvlookda cadeia de comando e criar um novo arquivo CSV redirecionando a saída para um arquivo.

Adicionamos mais dados ao “sample2.file”, removemos o csvsortcomando e criamos um novo arquivo chamado “sample3.csv”.

csvcut -c 3,2,4,5 amostra2.csv > amostra3.csv

Redirecionando csvcut para criar um novo arquivo chamado sample3.csv

Uma maneira segura de limpar 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 ponto e vírgula ” “, por exemplo.

Você não verá aspas nos campos citados. As únicas aspas que você verá são as aspas incorporadas nos dados do campo. Eles são mostrados como aspas simples. Localizá-los e substituí-los por um único apóstrofo ” '” substituirá as aspas duplas no arquivo CSV.

Usando localizar e substituir do LibreOffice Calc para substituir aspas por apóstrofos

Fazer localizar e substituir 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 ao redor dos campos citados. Você alterará apenas os valores de dados dos campos.

Alteramos todas as vírgulas nos campos com ponto e vírgula e todas as aspas incorporadas com apóstrofos e salvamos nossas alterações.

O arquivo CSV modificado

Em seguida, criamos um script chamado “field3.sh” para analisar “sample3.csv”.

#! /bin/bash

while IFS="," read -r sobrenome nome cargo e-mail

fazer

echo "Sobrenome: $sobrenome"

echo "Nome: $nome"

echo "Cargo: $jobtitle"

echo "Adicionar e-mail: $email"

eco ""

feito < <(cauda -n +2 amostra3.csv)

Vamos ver o que obtemos quando o executamos.

./field3.sh

Uma seção de CSV analisado corretamente

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 linguagem comum para dados de aplicativos. A maioria dos aplicativos que lidam com alguma forma de dados oferece suporte à importação e exportação de CSV. Saber como lidar com CSV – de maneira realista e prática – será de grande ajuda.