Apakah ada utilitas baris perintah untuk memindahkan file csv?


16

Diberikan file seperti itu

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

Apakah ada utilitas baris perintah untuk memindahkan konten sehingga output muncul seperti itu

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

Jawaban:


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

Mengingat usia pertanyaan ini, saya akan membenarkan perubahan saya terhadap hal ini sebagai yang diterima: a) Jawaban ini jauh lebih ringkas daripada Gilles python, b) rubytidak kalah portabel daripada python, dan c) ini juga menunjukkan cara untuk melewatkan input / output file. Bravo @luikore, dan selamat datang di Unix & Linux. Silakan tinggal.
Cory Klein

satu peringatan, di csv, bidang harus dikutip
yosefrow

@yosefrow Tidak perlu mengutip. Saya menguji perintah sebelum saya memposting jawaban ini.
luikore

ok seharusnya mengatakan "mungkin" kalau begitu. Itu tidak berhasil bagi saya sampai saya mengutip semua bidang. Mungkin ada hubungannya dengan konten data saya
yosefrow

16

Penguraian CSV tidak mudah dilakukan dengan alat POSIX saja, kecuali jika Anda menggunakan varian CSV yang disederhanakan tanpa kutip (sehingga koma tidak dapat muncul di bidang). Meski begitu tugas ini tampaknya tidak mudah dilakukan dengan awk atau pemrosesan teks lainnya menjadi alat. Anda dapat menggunakan Perl dengan Text::CSV, Python dengan csv, R dengan read.csv, Ruby dengan CSV , ... (Semua ini adalah bagian dari perpustakaan standar bahasa masing-masing kecuali untuk Perl.)

Misalnya, dalam 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

Solusi cepat & kotor :

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

apa yang diwakili oleh / tmp / l? Selain itu, bukankah akan lebih mudah untuk melewati kolom daripada garis, sesuatu di sepanjang garisfor ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
iruvar

Perhatikan bahwa ini berfungsi untuk input OP, tetapi hanya karena datanya memiliki jumlah baris dan kolom yang sama, yang biasanya tidak demikian.
tokland

csv memiliki spesifikasi mengenai kutipan dpuble, yaitu this "is" examplesel dikodekan "this ""is"" example"Saya tidak yakin jika solusi ini menangani kasus-kasus seperti itu dengan benar
Grzegorz Wierzowiecki

0

Dengan batasan yang disarankan (tanpa kutip, tidak ada koma yang disematkan), ini sederhana dalam awk (karena akan dalam perl tidak memperhitungkan lebih dari seribu baris CSV.pm, 2300 baris dalam csv.rb- python hanya memiliki 450 baris csv.py).

Ini adalah contoh untuk 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];
    }
}

By the way: contoh yang diberikan memiliki ruang ekstra yang diasumsikan OP akan dihapus; contoh lain tidak membahas detail ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.