Existe um utilitário de linha de comando para transpor um arquivo csv?

13

Dado um arquivo como esse

First,Last,Age
Cory,Klein,27
John Jacob,Smith,30

Existe um utilitário de linha de comando para transpor o conteúdo para que a saída apareça assim

First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
    
por Cory Klein 07.01.2013 / 23:59

5 respostas

1
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv
    
por 26.11.2018 / 12:19
15

A análise CSV não é feita facilmente apenas com as ferramentas POSIX, a menos que você esteja usando uma variante simplificada de CSV sem aspas (para que as vírgulas não apareçam em um campo). Mesmo assim, essa tarefa não parece fácil de fazer com o awk ou outro processamento de texto para a ferramenta. Você pode usar Perl com Text::CSV , Python com csv , R com read.csv , Ruby com CSV ,… (Todos destes são parte da biblioteca padrão do respectivo idioma, exceto Perl.)

Por exemplo, em Python:

import csv, sys
rows = list(csv.reader(sys.stdin))
writer = csv.writer(sys.stdout)
for col in xrange(0, len(rows[0])):
    writer.writerow([row[col] for row in rows])
    
por 08.01.2013 / 01:32
7

De link :

$ apt-get install csvtool

E, em seguida, converta

$ csvtool transpose input.csv > ouput.csv

Ou no pipeline

$ ... | csvtool transpose - | ...
    
por 05.10.2016 / 15:22
3

Um rápido & solução :

c=1
file=file.txt
num_lines=$(wc -l < "$file")

for ((i=0; i<num_lines; i++)) {
    cut -d, -f$c "$file" | paste -sd ','
    ((c++))
}
    
por 08.01.2013 / 00:58
0

Dada a limitação sugerida (sem citar, sem vírgulas incorporadas), é simples em awk (como seria em perl não tendo em conta mais de mil linhas em CSV.pm , 2300 linhas em csv.rb - python tem apenas 450 linhas em csv.py ).

Aqui está um exemplo para o awk:

#!/usr/bin/awk -f
BEGIN { width=0; }
{
    max = split($0, list, ",");
    # printf "%d:%s\n", NR, $0;
    if (width < max)
        width = max;
    for (n = 1; n <= max; ++n) {
        sub("^[     ]*","",list[n]);
        sub("[  ]*$","",list[n]);
        # printf "\t%d:%s\n", n, list[n];
        if ( columns[n] != "" ) {
            columns[n] = columns[n] ", ";
        }
        columns[n] = columns[n] list[n];
    }
}
END {
    # printf "%d columns\n", width;
    for (n = 1; n <= width; ++n) {
        printf "%s\n", columns[n];
    }
}

A propósito: o exemplo dado tinha espaço extra que OP assumia que seria removido; os outros exemplos não abordaram esse detalhe.

    
por 06.10.2016 / 00:49