Есть ли утилита командной строки для транспонирования csv-файла?


16

Учитывая файл, как так

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

Есть ли утилита командной строки для транспонирования содержимого, чтобы вывод выглядел так

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

Ответы:


6
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv

Учитывая возраст этого вопроса, я оправдываю свое изменение на это как принятое: а) этот ответ гораздо более лаконичен, чем Жиль python, б) rubyне менее переносим, ​​чем python, и в) это также показывает, как передать ввод / вывод файлы. Браво @luikore, и добро пожаловать в Unix & Linux. Пожалуйста, не торопись.
Кори Кляйн

одна оговорка, в csv, поля должны быть
заключены в

@yosefrow Не нужно цитировать. Я проверил команду, прежде чем опубликовать этот ответ.
Луйкоре

хорошо, должен был сказать "может" тогда. Это не сработало для меня, пока я не процитировал все поля. Может быть, связано с моим содержанием данных
yosefrow

16

Синтаксический анализ CSV нелегко выполнить только с помощью инструментов POSIX, если только вы не используете упрощенный вариант CSV без кавычек (чтобы запятые не могли появляться в поле). Даже тогда эта задача не кажется простой для выполнения с помощью awk или другой обработки текста в инструменте. Вы можете использовать Perl с Text::CSV, Python с csv, R с read.csv, Ruby с CSV ,… (Все это является частью стандартной библиотеки соответствующего языка, за исключением Perl.)

Например, в 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])


3

Быстрое и грязное решение для :

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++))
}

что представляет собой / tmp / l? Кроме того, не будет ли проще циклически проходить по столбцам, а не по линиям, что-то вродеfor ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
iruvar

Обратите внимание, что это работает для ввода OP, но только потому, что их данные имеют одинаковое количество строк и столбцов, что, как правило, не так.
Tokland

CSV имеет спецификацию относительно кавычек dpuble, т. е. this "is" exampleячейка закодирована. "this ""is"" example"Я не уверен, что это решение правильно обрабатывает такие случаи
Grzegorz Wierzowiecki

0

Учитывая предлагаемое ограничение (без кавычек, без встроенных запятых), это просто в awk (как это было бы в perl, не принимая во внимание более тысячи строк в CSV.pm, 2300 строк вcsv.rb - в python только 450 строк csv.py).

Вот пример для 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];
    }
}

Кстати: в данном примере было дополнительное пространство, которое, как предполагал OP, будет удалено; другие примеры не касались этой детали.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.