Apakah ada alat baris perintah yang kuat untuk memproses file csv?

47

Saya bekerja dengan file CSV dan kadang-kadang perlu memeriksa isi baris atau kolom dari baris perintah dengan cepat. Dalam banyak kasus cut, head, tail, dan teman-teman akan melakukan pekerjaan; namun, pemotongan tidak dapat dengan mudah menangani situasi seperti

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

Di sini, koma pertama adalah bagian dari bidang pertama, tetapi cut -d, -f1tidak setuju. Sebelum saya menulis solusi sendiri, saya bertanya-tanya apakah ada yang tahu alat bagus yang sudah ada untuk pekerjaan ini. Paling tidak, harus mampu menangani contoh di atas dan mengembalikan kolom dari file berformat CSV. Fitur lain yang diinginkan termasuk kemampuan untuk memilih kolom berdasarkan nama kolom yang diberikan di baris pertama, dukungan untuk gaya kutipan lainnya dan dukungan untuk file yang dipisahkan oleh tab.

Jika Anda tidak tahu alat seperti itu tetapi memiliki saran mengenai penerapan program seperti itu di Bash, Perl, atau Python, atau bahasa scripting umum lainnya, saya tidak akan keberatan dengan saran semacam itu.

Steven D
sumber

Jawaban:

38

Anda dapat menggunakan csvmodul Python .

Contoh sederhana:

import csv
reader = csv.reader(open("test.csv", "r"))
for row in reader:
    for col in row:
        print col
dogbane
sumber
Solusi terakhir saya adalah dalam python karena Perl saya terlalu berkarat. Terima kasih.
Steven D
2
Bahkan lebih baik, gunakan Panda . Ini secara eksplisit dirancang untuk bekerja dengan data tabular.
Josh
38

Saya mungkin sedikit terlambat, tetapi ada alat lain yang layak disebut: csvkit

http://csvkit.readthedocs.org/

Ini memiliki banyak alat baris perintah yang dapat:

  • memformat ulang file CSV,
  • konversi ke dan dari CSV dari berbagai format (JSON, SQL, XLS),
  • setara cut, grep, sortdan lain-lain, tapi CSV-sadar,
  • bergabung dengan file CSV yang berbeda,
  • lakukan pertanyaan SQL umum pada data dari file CSV.
romaia
sumber
6
Alat luar biasa yang memenuhi kriteria pertanyaan dengan sangat baik (khususnya tidak perlu menggunakan bahasa pemrograman dan dibuat dengan baik agar sesuai dengan utilitas Unix lainnya).
mm2001
15

Kedengarannya seperti pekerjaan untuk Perl Text::CSV.

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

Lihat dokumentasi untuk cara menangani nama kolom. Gaya pemisah dan kutipan dapat disesuaikan dengan parameter ke new. Lihat juga Text::CSV::Separatoruntuk menebak separator.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Apakah ada satu liner di mana Anda dapat memadatkan ini. Saya suka perl, tetapi hanya ketika saya bisa memohonnya langsung dari baris perintah daripada dengan skrip
Sridhar Sarnobat
2
@ user7000, kecuali shell Anda adalah (t)cshperintah itu akan berfungsi dengan baik pada prompt shell Anda. Anda selalu dapat menggabungkan baris-baris itu bersama jika Anda menginginkannya dalam satu baris. newline umumnya seperti ruang dalam sintaks perl seperti di C.
Stéphane Chazelas
Saya kira. Meskipun memencet lebih dari 2 baris menjadi 1 bukanlah yang saya maksud dengan satu kalimat. Saya berharap ada beberapa gula sintaksis yang akan melakukannya sebagian secara implisit (seperti bagaimana -emenciptakan loop implisit).
Sridhar Sarnobat
10

Saya telah menemukan csvfix, alat baris perintah melakukan pekerjaan dengan baik. Anda harus membuatnya sendiri:

http://neilb.bitbucket.org/csvfix

Itu melakukan semua hal yang Anda harapkan, memesan / memilih kolom, membagi / menggabungkan dan banyak Anda tidak ingin menghasilkan sisipan SQL dari data CSV dan data CSV yang berbeda.

Daniel Burke
sumber
8

Jika Anda ingin menggunakan baris perintah (dan tidak membuat seluruh program untuk melakukan pekerjaan itu), Anda ingin menggunakan baris , proyek yang sedang saya kerjakan: ini adalah antarmuka baris perintah untuk data tabular tetapi juga perpustakaan Python untuk digunakan dalam program Anda. Dengan antarmuka baris perintah, Anda dapat dengan cukup-mencetak data apa pun dalam CSV, XLS, XLSX, HTML atau format tabel lainnya yang didukung oleh perpustakaan dengan perintah sederhana:

rows print myfile.csv

Jika myfile.csvseperti ini:

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

Maka baris akan mencetak isinya dengan cara yang indah, seperti ini:

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

Menginstal

Jika Anda adalah pengembang Python dan sudah pipmenginstal pada mesin Anda, jalankan saja di dalam virtualenv atau dengan sudo:

pip install rows

Jika Anda menggunakan Debian:

sudo apt-get install rows

Fitur Keren Lainnya

Mengkonversi Format

Anda dapat mengkonversi antara format apa pun yang didukung:

rows convert myfile.xlsx myfile.csv

Menanyakan

Ya, Anda bisa menggunakan SQL ke file CSV:

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

Mengonversi output permintaan ke file alih-alih stdout juga dimungkinkan menggunakan --outputparameter.

Sebagai Perpustakaan Python

Anda juga dapat menggunakan program Python:

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

Berharap kamu menikmatinya!

Justlvaro Justen
sumber
6

R bukan bahasa pemrograman favorit saya, tetapi baik untuk hal-hal seperti ini. Jika file csv Anda adalah

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

Di dalam jenis penerjemah R

> 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

Sehubungan dengan permintaan Anda yang lain, untuk "kemampuan untuk memilih kolom berdasarkan nama kolom yang diberikan di baris pertama" lihat

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

Untuk "dukungan untuk gaya kutipan lainnya" lihat quoteargumen untuk read.csv (dan fungsi terkait). Untuk "dukungan untuk file-file yang dipisahkan-tab" lihat separgumen untuk read.csv (set sepke '\ t').

Untuk informasi lebih lanjut, lihat bantuan online.

> help(read.csv)
Faheem Mitha
sumber
Saya sangat akrab dengan R, tetapi tujuan saya adalah untuk memiliki sesuatu yang dapat saya gunakan dengan mudah dari Bash.
Steven D
1
@ Seven: R dapat dengan mudah dijalankan dari baris perintah, dengan cara yang sama seperti Python atau Perl, jika itu adalah satu-satunya masalah Anda. Lihat Rscript(bagian dari distribusi R dasar) atau paket addon littler. Anda bisa melakukan #!/usr/bin/env Rscriptatau serupa.
Faheem Mitha
Ah iya. Saya cukup mahir dalam R tetapi tidak banyak menggunakannya untuk membuat jenis utilitas ini. Saya memiliki sesuatu yang berfungsi dengan Python tetapi saya dapat mencoba membuat sesuatu di R juga.
Steven D
4

Miller adalah alat bagus lain untuk memanipulasi data berbasis nama, termasuk CSV (dengan header). Untuk mengekstrak kolom pertama file CSV, tanpa peduli namanya, Anda akan melakukan sesuatu seperti

printf '"first,column",second,third\n1,2,3\n' |
  mlr --csv --implicit-csv-header --headerless-csv-output cut -f 1
Stephen Kitt
sumber
Miller sangat mengesankan. Saya akan membandingkannya awk, tetapi sangat sadar DSV.
Derek Mahar
3

Atau, Anda bisa mencoba beberapa sihir awk . Namun, saya bukan pengguna awk yang baik dan tidak dapat mengkonfirmasi ini akan berfungsi dengan baik, dan bagaimana melakukannya.

rvs
sumber
9
Ini adalah satu Parser CSV awk yang saya gunakan beberapa waktu lalu .. Sepertinya dipikirkan dengan baik ... lorance.freeshell.org/csv
Peter.O
2

Untuk menggunakan python dari baris perintah, Anda dapat memeriksa pythonpy ( https://github.com/Russell91/pythonpy ):

$ echo $'a,b,c\nd,e,f' | py '[x[1] for x in csv.reader(sys.stdin)']
b
e
RussellStewart
sumber
2

coba "csvtool" paket ini adalah alat baris perintah yang berguna untuk menangani file CSV

Dominikus
sumber
1
Sudah disebutkan, dengan lebih detail ...
jasonwryan
2

cissy juga akan melakukan pemrosesan csv command-line. Ini ditulis dalam C (kecil / ringan) dengan paket rpm dan deb tersedia untuk sebagian besar distro.

Menggunakan contoh:

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

atau

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

atau

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

Ada juga perpustakaan Curry untuk membaca / menulis file dalam format CSV : CSV .

imz - Ivan Zakharyaschev
sumber
2
Apakah Anda keberatan memposting beberapa kode sampel, seperti jawaban Perl, Python, dan R? (Terutama karena Curry bukan bahasa skrip unix yang umum.)
Gilles 'SO- stop being evil'
@Gilles: Ya, Anda benar, saya harus memposting beberapa kode sampel untuk membuat jawabannya lebih baik. Saya akan melakukan ini sebentar lagi.
imz - Ivan Zakharyaschev
1

Structured Text Tools dari github repo memiliki daftar alat baris perintah linux yang berguna. Secara khusus, bagian Pemisah Nilai Daftar daftar beberapa alat yang mampu CSV yang secara langsung mendukung operasi yang diminta.

JonDeg
sumber
1

Salah satu alat terbaik adalah Miller ( http://johnkerl.org/miller/doc/index.html ). Itu seperti awk, sed, cut, join, dan sortir untuk data yang diindeks nama seperti CSV, TSV, dan JSON tabular.

Sebagai contoh

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

Memberi anda

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

Jika Anda menginginkan TSV

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

memberi Anda (mungkin untuk menghapus tajuk)

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

Jika Anda ingin kolom pertama dan ketiga, ubah urutannya

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

Memberi anda

 34.5,"this, is the first entry"
aborruso
sumber
1

Jika Anda menginginkan alat visual / interaktif di terminal, saya sepenuh hati merekomendasikan VisiData.

masukkan deskripsi gambar di sini

Ini memiliki tabel frekuensi (ditunjukkan di atas), pivot, melting, scatterplots, filtering / komputasi menggunakan Python, dan banyak lagi.

Anda dapat mengirimkan file csv seperti itu

vd hello.csv

Ada csv opsi khusus: --csv-dialect, --csv-delimiter, --csv-quotechar, dan --csv-skipinitialspaceuntuk fine-tuned penanganan file csv.

DameDebugger
sumber
0

Solusi awk

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
Srini
sumber