Есть ли утилита командной строки для транспонирования 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.