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

この質問の年齢を考えると、私はこれを受け入れられたものとして変更することを正当化します:a)この答えは、Gilles 'よりはるかに簡潔でpython、b)ruby移植性は劣らずpython、c)これは入出力を渡す方法も示していますファイル。Bravo @ luikore、UnixおよびLinuxへようこそ。頑張ってください。
コリークライン

1つの警告は、CSV形式で、フィールドは引用符で囲む必要があります
yosefrow

@yosefrow引用する必要はありません。この回答を投稿する前に、コマンドをテストしました。
ルイコレ

[OK]が「5月」と言っているはずです。すべてのフィールドを引用するまで、うまくいきませんでした。私のデータ内容としなければならないかもしれません
yosefrow

16

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


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の入力に対して機能しますが、データの行と列の数が同じであるためです。通常はそうではありません。
トックランド

CSVはdpuble引用符に関する仕様を持っている、すなわちthis "is" exampleセルがエンコードされている"this ""is"" example"私は、このソリューションのハンドルこのような場合であれば、適切に納得していないです
グジェゴシWierzowiecki

0

提案された制限(引用符なし、埋め込みコンマなし)を考えると、それはawkで簡単です(perlでは1000行以上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が削除すると想定した余分なスペースがありました。他の例では、この詳細に対処していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.