Existe um feitiço na linha de comando para soltar uma coluna em um arquivo CSV?

32

Ter um arquivo com o seguinte conteúdo:

1111,2222,3333,4444
aaaa,bbbb,cccc,dddd

Eu procuro obter um arquivo igual ao original, mas sem uma n-ésima coluna como, para n = 2 (ou pode ser 3)

1111,2222,4444
aaaa,bbbb,dddd

ou, para n = 0 (ou pode ser 1)

2222,3333,4444
bbbb,cccc,dddd

Um arquivo real pode ter gigabytes com dezenas de milhares de colunas.

Como sempre, nesses casos, suspeito que os mágicos da linha de comando possam oferecer uma solução elegante ... :-)

No meu caso real, preciso soltar duas primeiras colunas, o que pode ser feito soltando uma primeira coluna duas vezes em uma sequência, mas suponho que seria mais interessante generalizar um pouco.

Ivan
fonte
Os campos são garantidos para não conter ,? (Ou seja, ,só é usado como um separador de campos).
um CVn 21/03
@ MichaelKjörling, seria bom ter uma solução mais flexível, mas no meu caso - sim: o separador é ,e nunca ocorre dentro de um campo.
21412 Ivan
Nesse caso, a resposta de Scott deve ser exatamente a coisa.
a CVn

Respostas:

47

Eu acredito que isso é específico para cortar a partir dos coreutils GNU:

$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd

Normalmente você especifica os campos que deseja via -f, mas adicionando --complement você inverte o significado, naturalmente. De 'man cut':

--complement
    complement the set of selected bytes, characters or fields

Uma ressalva: se alguma das colunas contiver uma vírgula, ela será cortada, porque o corte não é um analisador de CSV da mesma maneira que uma planilha. Muitos analisadores têm idéias diferentes sobre como lidar com vírgulas de escape no CSV. Para o caso simples de CSV, na linha de comando, o corte ainda é o caminho a percorrer.

Scott McClung
fonte
4
Isso funciona bem desde que seja um arquivo CSV simples. Se alguma das colunas for uma string com uma vírgula, ela será cutdisparada porque não é um analisador de CSV. Se um campo CSV tiver um separador de campo em seu valor, ele estará entre aspas. Btw, sobre o assunto cut, -fassume intervalos de campo. cut -f, -d3-produzirá o terceiro campo, removendo os dois primeiros.
Alexios #
2
Você quer dizercut -d, -f3-
Inutil
@ Alexios, esse é um bom argumento. Eu realmente nunca lido com CSV "real", apenas o subconjunto simples. Vou editar minha resposta para refletir isso.
21412 Scott McClung
@ Useless: Porra, sim. É isso que chamo de minha 'dislexia cortada' atingindo novamente. suspiro . Scott: arquivos CSV são bestas complicadas. Muitos sub-formatos diferentes, alguns dos quais nem são C SV, mas convencionalmente são chamados assim.
21312 Alexios
Isso imprime o novo CSV no meu terminal - como faço para substituir a entrada (ou talvez gravar em um novo arquivo, parece que o OP estava procurando também)?
Max Ghenis
12

Se os dados forem simplesmente constituídos por colunas separadas por vírgula:

cut -d , -f 1-2,4-

Você também pode usar o awk, mas é um pouco estranho, porque ao limpar um campo é fácil, remover o separador exige algum trabalho. Se você não tem um campo vazio, não é tão ruim:

awk -F , 'BEGIN {OFS=FS}  {$3=""; sub(",,", ","); print}'

Se você possui um CSV real, onde as vírgulas podem aparecer dentro dos campos, se citadas corretamente, você precisa de uma biblioteca CSV real .

Gilles 'SO- parar de ser mau'
fonte