Bir csv dosyasını aktarmak için bir komut satırı yardımcı programı var mı?


16

Bunun gibi bir dosya verildi

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

Çıktı böyle görünecek şekilde içerikleri aktarmak için bir komut satırı yardımcı programı var mı

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

Yanıtlar:


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

Bu sorunun yaşı göz önüne alındığında, bu değişikliği benimsediğim gibi kabul edeceğim: a) Bu cevap Gilles'ten çok daha özlüdür python, b) Bundan rubydaha az taşınabilir değildir pythonve c) bu da giriş / çıkışın nasıl geçileceğini gösterir Dosyalar. Bravo @luikore ve Unix & Linux'a hoş geldiniz. Lütfen etrafta dolaş.
Cory Klein

bir uyarı, csv, alanlar alıntı olmalıdır
yosefrow

@yosefrow Alıntı yapmaya gerek yok. Bu cevabı göndermeden önce komutu test ettim.
luikore

Tamam o zaman "olabilir" demeliydi. Tüm alanları alıntılayana kadar benim için işe yaramadı. Veri içeriğimle ilgili olabilir
yosefrow

16

CSV ayrıştırma işlemi, tırnak işareti olmadan basitleştirilmiş bir CSV varyantı kullanmadığınız sürece yalnızca POSIX araçlarıyla kolayca yapılamaz (böylece virgül bir alanda görünemez). O zaman bile bu görev awk veya diğer metin işleme aracıyla yapmak kolay görünmüyor. Perl ile Text::CSV, Python ile csv, R ile read.csv, CSV ile Ruby ,… kullanabilirsiniz. (Bunların hepsi Perl hariç ilgili dilin standart kütüphanesinin bir parçasıdır.)

Örneğin, Python'da:

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

Hızlı ve kirli bir çözümü:

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 neyi temsil eder? Ayrıca, satırlar yerine sütunlar arasında döngü yapmak daha kolay olmaz mıydı, çizgiler boyunca bir şeyfor ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
iruvar

Bunun OP girdisi için işe yaradığını, ancak verilerinin aynı sayıda satır ve sütun içerdiğinden, genellikle böyle olmadığını unutmayın.
tokland

csv dpuble tırnaklar ile ilgili şartname vardır, yani this "is" examplehücre kodlanmış "this ""is"" example"Bu çözüm bu gibi durumlarda düzgün işler eğer ikna değilim
Grzegorz Wierzowiecki

0

Önerilen sınırlama göz önüne alındığında (alıntı yok, gömülü virgül yok), awk içinde basittir (bin satırdan fazla dikkate almayan perl'de olacağı için CSV.pm, 2300 satır içi csv.rb- python'un sadece 450 satırı vardır csv.py).

Awk için bir örnek:

#!/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];
    }
}

Bu arada: verilen örnekte OP'nin kaldırılacağı varsayılan ekstra alan vardı; diğer örnekler bu ayrıntıya değinmemiştir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.