CSV dosyalarını işlemek için sağlam bir komut satırı aracı var mı?


47

CSV dosyalarıyla çalışıyorum ve bazen satır veya sütunun içeriğini komut satırından hızlıca kontrol etmem gerekiyor. Birçok durumda cut, head, tail, ve işi yapacak arkadaşlar; ancak, kesim gibi durumlarla kolayca baş edemezsiniz

"this, is the first entry", this is the second, 34.5

Burada, ilk virgül ilk alanın bir parçasıdır, ancak cut -d, -f1aynı fikirde değildir. Kendime bir çözüm yazmadan önce, bu iş için zaten mevcut olan iyi bir araç bilen var mı merak ediyorum. En azından yukarıdaki örneği ele almalı ve CSV formatlı bir dosyadan bir sütun döndürmelidir. İstenen diğer özellikler arasında, ilk satırda verilen sütun adlarına göre sütun seçme yeteneği, diğer alıntı stilleri için destek ve sekmeyle ayrılmış dosyalar için destek sayılabilir.

Böyle bir aracı bilmiyorsanız, ancak böyle bir programın Bash, Perl veya Python veya diğer genel betik dillerinde uygulanmasıyla ilgili öneriniz varsa, bu tür önerilere aldırış etmem.

Yanıtlar:


38

Python csvmodülünü kullanabilirsiniz .

Basit bir örnek:

import csv
reader = csv.reader(open("test.csv", "r"))
for row in reader:
    for col in row:
        print col

Son çözümüm Perl'im çok paslı olduğu için python'du. Teşekkürler.
Steven D,

2
Daha da iyisi, Pandaları kullanın . Açıkça tablo verilerle çalışmak üzere tasarlanmıştır.
Josh,

38

Muhtemelen biraz geç kaldım, ama bahsetmeye değer başka bir araç var: csvkit

http://csvkit.readthedocs.org/

Aşağıdakileri yapabilen çok sayıda komut satırı aracı vardır:

  • CSV dosyalarının yeniden biçimlendirilmesi,
  • CSV'ye çeşitli biçimlerden (JSON, SQL, XLS) dönüştürmek,
  • eşdeğer cut, grep, sortve diğerleri, ancak CSV-aware
  • Farklı CSV dosyalarına katılmak,
  • CSV dosyalarındaki veriler üzerinde genel SQL sorguları yapabilir.

6
Soru kriterlerini mükemmel bir şekilde karşılayan mükemmel bir araç (özellikle bir programlama diline geçmeyi gerektirmez ve diğer Unix araçlarına uyacak şekilde hazırlanmıştır).
mm2001

15

İle Perl için bir iş gibi geliyor Text::CSV.

perl -MText::CSV -pe '
    BEGIN {$csv = Text::CSV->new();}
    $csv->parse($_) or die;
    @fields = $csv->fields();
    print @fields[1,3];
'

Sütun adlarının nasıl kullanılacağına ilişkin belgelere bakın. Ayırıcı ve tırnak tarzı parametreleri ile ayarlanabilir new. Text::CSV::SeparatorAyırıcı tahmini için ayrıca bakınız .


Bunu sıkıştırabileceğiniz bir astar var mı?
Perl'i

2
@ user7000, kabuğunuz (t)cshbu komut kabuğunuzun isteminde gayet iyi sonuç vermediyse . Tek bir çizgide isterseniz, her zaman bu çizgileri birleştirebilirsiniz. satır sadece C gibi Perl sözdiziminde alanı gibi genel olarak
Stéphane Chazelas

Sanırım. 1'den 2 satırdan fazla ezmek, aslında tek bir astarla kastettiğim şey değil. Bazılarını dolaylı olarak yapacak bir sözdizimsel şekerin olmasını umuyordum ( -eörtük bir döngü oluşturduğu gibi ).
Sridhar Sarnobat 12:17

10

Csvfix'i buldum, bir komut satırı aracı işi iyi yapıyor. Ancak bunu kendiniz yapmanız gerekecek:

http://neilb.bitbucket.org/csvfix

Beklediğiniz her şeyi yapar, sütunları sipariş eder / seçer, ayırır / birleştirir ve CSV verilerinden SQL ekleri oluşturmak ve CSV verilerini değiştirmek istemezsiniz.


8

Komut satırını kullanmak istiyorsanız (ve işi yapmak için bütün bir program oluşturmazsanız), üzerinde çalıştığım bir proje olan satırları kullanmak istersiniz : tabular halinde veri için bir komut satırı arayüzü. programlarınızda kullanılacak bir Python kütüphanesi. Komut satırı arayüzü ile CSV, XLS, XLSX, HTML veya kütüphane tarafından desteklenen herhangi bir tablo biçimindeki verileri basit bir komutla kolayca yazdırabilirsiniz:

rows print myfile.csv

Eğer myfile.csvböyle ise:

state,city,inhabitants,area
RJ,Angra dos Reis,169511,825.09
RJ,Aperibé,10213,94.64
RJ,Araruama,112008,638.02
RJ,Areal,11423,110.92
RJ,Armação dos Búzios,27560,70.28

Sonra satırlar içeriği şöyle güzel bir şekilde basar, şöyle:

+-------+-------------------------------+-------------+---------+
| state |              city             | inhabitants |   area  |
+-------+-------------------------------+-------------+---------+
|    RJ |                Angra dos Reis |      169511 |  825.09 |
|    RJ |                       Aperibé |       10213 |   94.64 |
|    RJ |                      Araruama |      112008 |  638.02 |
|    RJ |                         Areal |       11423 |  110.92 |
|    RJ |            Armação dos Búzios |       27560 |   70.28 |
+-------+-------------------------------+-------------+---------+

yükleme

Bir Python geliştiricisiyseniz ve pipmakinenize zaten yüklediyseniz, yalnızca bir sanalenv içinde veya ile çalıştırın sudo:

pip install rows

Debian kullanıyorsanız:

sudo apt-get install rows

Diğer Harika Özellikler

Biçimleri dönüştürme

Desteklenen herhangi bir format arasında dönüştürebilirsiniz:

rows convert myfile.xlsx myfile.csv

sorgulama

Evet, SQL'i bir CSV dosyasına kullanabilirsiniz:

$ rows query 'SELECT city, area FROM table1 WHERE inhabitants > 100000' myfile.csv
+----------------+--------+
|      city      |  area  |
+----------------+--------+
| Angra dos Reis | 825.09 |
|       Araruama | 638.02 |
+----------------+--------+

Sorgu çıktısının stdout yerine bir dosyaya dönüştürülmesi de --outputparametre kullanılarak mümkündür .

Python Kütüphanesi Olarak

Python programlarınızda da yapabilirsiniz:

import rows
table = rows.import_from_csv('myfile.csv')
rows.export_to_txt(table, 'myfile.txt')
# `myfile.txt` will have same content as `rows print` output

Umarım tadını çıkarırsın!


6

R benim favori programlama dilim değil, fakat bunun gibi şeyler için iyidir Csv dosyanız varsa

***********
foo.csv
***********
 col1, col2, col3
"this, is the first entry", this is the second, 34.5
'some more', "messed up", stuff

R tercüman tipinin içinde

> x=read.csv("foo.csv", header=FALSE)

> x
                     col1                col2   col3
1 this, is the first entry  this is the second   34.5
2              'some more'           messed up  stuff
> x[1]  # first col
                      col1
1 this, is the first entry
2              'some more'
> x[1,] # first row
                      col1                col2  col3
1 this, is the first entry  this is the second  34.5

Diğer isteklerinizle ilgili olarak, "ilk satırda verilen sütun adlarına göre sütun seçme yeteneği" için, bkz.

> x["col1"]
                      col1
1 this, is the first entry
2              'some more'

"Diğer alıntı stilleri için destek" quoteiçin read.csv (ve ilgili işlevler) argümanına bakın . " sepSekmeyle ayrılmış dosyalar için destek" için read.csv değişkenine bakın ( sep'\ t' olarak ayarlayın).

Daha fazla bilgi için, çevrimiçi yardıma bakın.

> help(read.csv)

R'ye çok aşinayım, ancak amacım Bash'den kolayca kullanabileceğim bir şeydi.
Steven D

1
@Steven: Eğer tek endişeniz buysa, R, Python veya Perl ile aynı şekilde komut satırından kolayca çalıştırılabilir. Bkz. Rscript(Baz dağılımının bir parçası) veya addon paketi littler. Yapabilir #!/usr/bin/env Rscriptveya benzer.
Faheem Mitha

Ah evet. R konusunda oldukça bilgiliyim ama bu tür bir yardımcı program oluşturmak için fazla kullanmamıştım. Python'da çalışan bir işim var ama R'de de bir şeyler yaratmaya çalışabilirim.
Steven D


4

Miller , CSV (başlıklı) dahil olmak üzere, isme dayalı verileri yönetmek için güzel bir araçtır. Bir CSV dosyasının ilk sütununu çıkarmak için, adını önemsemeden, böyle bir şey yaparsınız

printf '"first,column",second,third\n1,2,3\n' |
  mlr --csv --implicit-csv-header --headerless-csv-output cut -f 1

Miller çok etkileyici. Bunu karşılaştırırdım awk, ama son derece DSV farkındaydı.
Derek Mahar

3

Veya biraz garip sihir deneyebilirsiniz . Bununla birlikte, ben iyi bir awk kullanıcısı değilim ve bunun düzgün çalışacağını ve bunun nasıl yapılacağını onaylayamıyorum.


9
İşte bir süre önce kullandığım bir awk CSV Ayrıştırıcısı .. Oldukça iyi düşünülmüş görünüyor ... lorance.freeshell.org/csv
Peter.O



2

Bu paketi "csvtool" deneyin bu CSV dosyalarını işlemek için kullanışlı komut satırı aracı


1
Zaten daha ayrıntılı olarak bahsetmiştim ...
jasonwryan

2

cissy ayrıca komut satırı csv işleme yapacak. Çoğu dağıtıma uygun, rpm ve deb paketleri ile birlikte C (küçük / hafif) olarak yazılmıştır.

Örnek kullanarak:

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 1
"this, is the first entry"

veya

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2
 this is the second

veya

echo '"this, is the first entry", this is the second, 34.5' | cissy -c 2-
 this is the second, 34.5

1

CSV formatında dosya okumak / yazmak için bir Curry kütüphanesi de vardır : CSV .


2
Perl, Python ve R cevapları gibi bazı örnek kodlar gönderir misiniz? (Özellikle Curry yaygın bir unix betik dili olmadığı için.)
Gilles 'ÇÖZME'

@Gilles: Evet, haklısın, cevabı daha iyi hale getirmek için bazı örnek kodlar göndermeliyim. Bunu bir süre sonra yapacağım.
imz - Ivan Zakharyaschev



1

En iyi araçlardan biri Miller'dir ( http://johnkerl.org/miller/doc/index.html ). CSV, TSV ve tablo JSON gibi ad dizinli veriler için awk, sed, cut, join ve sıralama gibi.

Örnek olarak

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --icsv --implicit-csv-header cat

sana verir

1=this, is the first entry,2= this is the second,3= 34.5

TSV istiyorsanız

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --c2t --implicit-csv-header cat

size verir (başlığı kaldırmak mümkündür)

1       2       3
this, is the first entry         this is the second      34.5

Birinci ve üçüncü sütunu istiyorsanız, sıralarını değiştirme

echo '"this, is the first entry", this is the second, 34.5' | \
mlr --csv --implicit-csv-header --headerless-csv-output cut -o -f 3,1

sana verir

 34.5,"this, is the first entry"

1

Terminalde görsel / etkileşimli bir araç istiyorsanız, kalbimle VisiData'yı tavsiye ederim.

görüntü tanımını buraya girin

Frekans tabloları (yukarıda gösterilmiştir), pivot, erime, saçılma noktaları, Python kullanarak filtreleme / hesaplama ve daha pek çok şey vardır.

Böyle csv dosyaları iletebilirsiniz

vd hello.csv

Csv özgü seçeneği vardır: --csv-dialect, --csv-delimiter, --csv-quotechar, ve --csv-skipinitialspaceiçin csv dosyalarını işleme ince ayarlı.


0

Bir awk çözümü

awk -vq='"' '
func csv2del(n) {
  for(i=n; i<=c; i++)
    {if(i%2 == 1) gsub(/,/, OFS, a[i])
    else a[i] = (q a[i] q)
    out = (out) ? out a[i] : a[i]}
  return out}
{c=split($0, a, q); out=X;
  if(a[1]) $0=csv2del(1)
  else $0=csv2del(2)}1' OFS='|' file
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.