web-dev-qa-db-ja.com

csvファイルを転置するコマンドラインユーティリティはありますか?

そのようなファイルが与えられた

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

内容を転置して出力がそのように表示されるコマンドラインユーティリティはありますか

First,Cory,John Jacob
Last,Klein,Smith
Age,27,30
16
Cory Klein
Ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv
6
luikore

CSVの解析は、引用符のない簡略化されたCSVバリアントを使用しない限り(カンマがフィールドに表示されないようにするため)、POSIXツールだけでは簡単に実行できません。それでも、このタスクはawkやその他のテキスト処理ツールで行うのは簡単ではないようです。 Perlは Text::CSV 、Python with csv 、R with read.csv 、Ruby with [〜#〜] 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])

From https://stackoverflow.com/a/2776078 から:

$ apt-get install csvtool

そして変換する

$ csvtool transpose input.csv > ouput.csv

またはパイプラインで

$ ... | csvtool transpose - | ...
12

迅速で汚い bash ソリューション:

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++))
}
3
Gilles Quenot

提案された制限(引用符なし、埋め込まれたコンマなし)を考えると、これはawkでは単純です(PerlではCSV.pmの1000行以上、csv.rbの2300行は考慮されていないため、— = = pythonはcsv.pyに450行しかありません)。

これは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が削除されると想定した余分なスペースがありました。他の例では、この詳細は扱われていません。

0
Thomas Dickey