Substituindo sublinhado por vírgula e removendo aspas duplas em CSV

10

Eu tenho um arquivo CSV como

input.csv

"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
"1_1_0_0_79"
"1_1_0_0_80"
"1_1_0_0_81"
"1_1_0_0_82"
"1_1_0_0_83"
"1_1_0_0_84"
"1_1_0_0_85"

............. e assim por diante.

Eu preciso converter este arquivo CSV em

result.csv 

1,1,0,0,76
1,1,0,0,77
1,1,0,0,78
1,1,0,0,79
1,1,0,0,80
1,1,0,0,81
1,1,0,0,82
1,1,0,0,83
1,1,0,0,84
1,1,0,0,85
    
por RKR 19.01.2017 / 03:19

5 respostas

24

A maneira mais simples é usar tr

$ tr '_' ',' < input.csv | tr -d '"'                  
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

A maneira como isso funciona é que tr recebe dois argumentos - conjunto de caracteres a serem substituídos e sua substituição. Neste caso, temos apenas conjuntos de 1 caractere. Redirecionamos o fluxo de stdin de input.csv input tr via operador de shell < e canalizamos a saída resultante para tr -d '"' para excluir aspas duplas.

Mas awk também pode fazer isso.

$ cat input.csv
"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
$ awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

A maneira como isso funciona é um pouco diferente: o awk lê cada arquivo linha por linha, cada script in-line sendo /Pattern match/{ codeblock}/Another pattern/{code block for this pattern} . Aqui não temos um padrão, então significa executar o codeblock para cada linha. A função gsub() é usada para substituição global em uma linha, portanto, usamos para substituir sublinhados por vírgulas e aspas duplas com uma string nula (excluindo efetivamente o caractere). O 1 está no lugar da correspondência de padrões com o bloco de códigos ausentes, cujo padrão é simplesmente imprimir a linha; em outras palavras, o codeblock com gsub() faz o trabalho e 1 imprime o resultado.

Use o redirecionamento do shell ( > ) para enviar a saída para um novo arquivo:

 awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv > output.csv
    
por 19.01.2017 / 03:23
13

Apenas como alternativa, você também pode usar este comando sed :

$ sed -e 's/_/,/g' -e 's/"//g' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78
    
por 19.01.2017 / 03:34
10

Perl, a "cadeia do exército suíço" do processamento de texto em linha de comando, também pode fazer isso. A sintaxe é (não coincidentemente) bastante semelhante aos exemplos tr e sed :

perl -pe 'tr/_"/,/d' input.csv > result.csv

ou:

perl -pe 's/_/,/g; s/"//g' input.csv > result.csv

Mas, honestamente, se você não quer gastar tempo para aprender uma nova linguagem de programação (que é realmente o que o awk, o Perl e o sed e outras ferramentas como eles são) apenas para essa tarefa básica, você poderia faça isso em qualquer editor de texto que ofereça suporte à pesquisa e substituição:

  1. Abra o arquivo CSV em seu editor de texto favorito (como gedit, kate, mousepad, etc.; até mesmo o Notepad ou Wordpad antigo no Windows podem fazer isso).

  2. Selecione "Pesquisar e substituir" no menu (normalmente encontrado em "Editar", se não houver um menu "Pesquisar" separado).

  3. Insira _ na caixa de pesquisa e , na caixa de substituição.

  4. Clique em "Substituir tudo".

  5. Repita com " na caixa de pesquisa e nada na caixa de substituição.

  6. Salve o arquivo.

Agora, se você precisar fazer isso para 100 ou 1000 arquivos, em vez de apenas um, o aprendizado de uma nova ferramenta de linha de comando começa a fazer sentido. E, claro, quando você souber usar Perl ou sed ou qualquer outra coisa, economizará muito tempo e esforço com tarefas semelhantes mais tarde. Mas, para um trabalho único que você não espera fazer novamente, às vezes, uma ferramenta básica interativa, como um editor de texto, é a solução mais simples.

    
por 19.01.2017 / 06:08
3

Você também pode fazer isso com vim .

Abra o arquivo: vim input.csv e, em seguida, use a ferramenta de pesquisa avançada vim s . Digite dois pontos ( : ) para entrar no modo de comando e execute comandos como este:

:%s's/_/,/g'  -- Replaces all occurrences of _ with , in the current file.
:s/\"//g -- Replaces all occurrences of " with nothing in the current file.

Mais ou menos os mesmos comandos da resposta da IanC, mas dentro de vim em vez de usar sed .

    
por 19.01.2017 / 17:28
2

Por que não apenas alterar os valores padrão dos valores de separação de entrada e saída

awk -F "_" 'BEGIN { OFS="," }; {gsub(/\"/,""); print $1,$2,$3,$4,$5}' input.csv
    
por 19.01.2017 / 18:10