Có một công cụ dòng lệnh mạnh mẽ để xử lý các tệp csv?


47

Tôi làm việc với các tệp CSV và đôi khi cần kiểm tra nhanh nội dung của một hàng hoặc cột từ dòng lệnh. Trong nhiều trường hợp cut, head, tail, và bạn bè sẽ thực hiện công việc; tuy nhiên, cắt không thể dễ dàng xử lý các tình huống như

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

Ở đây, dấu phẩy đầu tiên là một phần của trường đầu tiên, nhưng cut -d, -f1không đồng ý. Trước khi tôi tự viết một giải pháp, tôi đã tự hỏi liệu có ai biết về một công cụ tốt đã tồn tại cho công việc này không. Ít nhất, nó sẽ phải có thể xử lý ví dụ trên và trả về một cột từ tệp định dạng CSV. Các tính năng mong muốn khác bao gồm khả năng chọn các cột dựa trên tên cột được đưa ra ở hàng đầu tiên, hỗ trợ cho các kiểu trích dẫn khác và hỗ trợ cho các tệp được phân tách bằng tab.

Nếu bạn không biết về một công cụ như vậy nhưng có các đề xuất liên quan đến việc triển khai một chương trình như vậy trong Bash, Perl hoặc Python hoặc các ngôn ngữ kịch bản thông thường khác, tôi sẽ không bận tâm đến các đề xuất đó.

Câu trả lời:


38

Bạn có thể sử dụng csvmô-đun của Python .

Một ví dụ đơn giản:

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

Giải pháp cuối cùng của tôi là ở trăn vì Perl của tôi quá gỉ. Cảm ơn.
Steven D

2
Thậm chí tốt hơn, sử dụng Pandas . Nó được thiết kế rõ ràng để làm việc với dữ liệu dạng bảng.
Josh

38

Tôi có lẽ hơi muộn một chút, nhưng có một công cụ khác đáng nói: csvkit

http://csvkit.readthedocs.org/

Nó có rất nhiều công cụ dòng lệnh có thể:

  • định dạng lại các tệp CSV,
  • chuyển đổi sang và từ CSV từ các định dạng khác nhau (JSON, SQL, XLS),
  • tương đương với cut, grep, sortvà những người khác, nhưng CSV-aware,
  • tham gia các tệp CSV khác nhau,
  • thực hiện các truy vấn SQL chung trên dữ liệu từ các tệp CSV.

6
Một công cụ tuyệt vời đáp ứng các tiêu chí câu hỏi tuyệt vời (đặc biệt là nó không yêu cầu nhảy vào ngôn ngữ lập trình và được chế tạo tốt để phù hợp với các tiện ích Unix khác).
mm2001

15

Âm thanh như một công việc cho Perl với Text::CSV.

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

Xem tài liệu hướng dẫn cách xử lý tên cột. Dấu phân cách và kiểu trích dẫn có thể được điều chỉnh với các tham số new. Xem thêm Text::CSV::Separatorđể đoán phân cách.


Có một lớp lót bạn có thể nén nó vào. Tôi thích perl, nhưng chỉ khi tôi có thể gọi nó trực tiếp từ dòng lệnh chứ không phải bằng một kịch bản
Sridhar Sarnobat

2
@ user7000, trừ khi shell của bạn là (t)cshlệnh đó sẽ chỉ hoạt động tốt tại dấu nhắc của shell của bạn. Bạn luôn có thể nối các dòng đó với nhau nếu bạn muốn nó trên một dòng. dòng mới nói chung giống như khoảng trắng trong cú pháp perl như trong C.
Stéphane Chazelas

Tôi đoán. Mặc dù ép nhiều hơn 2 dòng thành 1 không phải là điều tôi thực sự muốn nói với một lớp lót. Tôi đã hy vọng có một số đường cú pháp sẽ làm một số điều đó hoàn toàn (như cách -etạo ra một vòng lặp ngầm).
Sridhar Sarnobat

10

Tôi đã tìm thấy csvfix, một công cụ dòng lệnh thực hiện công việc tốt. Bạn sẽ cần phải tự làm nó:

http://neilb.bitbucket.org/csvfix

Nó thực hiện tất cả những điều bạn mong đợi, sắp xếp / chọn cột, phân tách / hợp nhất và nhiều thứ bạn không muốn tạo chèn SQL từ dữ liệu CSV và dữ liệu CSV khác nhau.


8

Nếu bạn muốn sử dụng dòng lệnh (và không tạo toàn bộ chương trình để thực hiện công việc), bạn muốn sử dụng các hàng , một dự án tôi đang thực hiện: đó là giao diện dòng lệnh cho dữ liệu dạng bảng nhưng cũng một thư viện Python để sử dụng trong các chương trình của bạn. Với giao diện dòng lệnh, bạn có thể in đẹp bất kỳ dữ liệu nào dưới dạng CSV, XLS, XLSX, HTML hoặc bất kỳ định dạng bảng nào khác được thư viện hỗ trợ bằng một lệnh đơn giản:

rows print myfile.csv

Nếu myfile.csvlà như thế này:

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

Sau đó, các hàng sẽ in nội dung một cách đẹp mắt, như thế này:

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

Cài đặt

Nếu bạn là nhà phát triển Python và đã pipcài đặt trên máy của mình, chỉ cần chạy bên trong virtualenv hoặc với sudo:

pip install rows

Nếu bạn đang sử dụng Debian:

sudo apt-get install rows

Các tính năng thú vị khác

Chuyển đổi định dạng

Bạn có thể chuyển đổi giữa bất kỳ định dạng được hỗ trợ:

rows convert myfile.xlsx myfile.csv

Truy vấn

Có, bạn có thể sử dụng SQL vào tệp CSV:

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

Chuyển đổi đầu ra của truy vấn thành một tệp thay vì thiết bị xuất chuẩn cũng có thể sử dụng --outputtham số.

Là một thư viện Python

Bạn cũng có thể trong các chương trình Python của mình:

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

Hy vọng là bạn sẽ thích nó!


6

R không phải là ngôn ngữ lập trình yêu thích của tôi, nhưng nó tốt cho những thứ như thế này. Nếu tập tin csv của bạn là

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

Bên trong loại trình thông dịch 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

Đối với các yêu cầu khác của bạn, về "khả năng chọn các cột dựa trên các tên cột được đưa ra trong hàng đầu tiên", hãy xem

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

Để biết "hỗ trợ cho các kiểu trích dẫn khác", hãy xem quoteđối số để read.csv (và các hàm liên quan). Để biết "hỗ trợ cho các tệp được phân tách bằng tab", hãy xem sepđối số thành read.csv (được đặt septhành '\ t').

Để biết thêm thông tin xem trợ giúp trực tuyến.

> help(read.csv)

Tôi rất quen thuộc với R, nhưng mục tiêu của tôi là có thứ gì đó tôi có thể sử dụng dễ dàng từ Bash.
Steven D

1
@Steven: R có thể dễ dàng được chạy từ dòng lệnh, giống như Python hoặc Perl, nếu đó là mối quan tâm duy nhất của bạn. Xem Rscript(một phần của phân phối R cơ sở) hoặc gói addon littler. Bạn có thể làm #!/usr/bin/env Rscripthoặc tương tự.
Faheem Mitha

À đúng rồi. Tôi khá thành thạo R nhưng đã không sử dụng nó nhiều để tạo ra loại tiện ích này. Tôi có một cái gì đó hoạt động trong Python nhưng tôi cũng có thể cố gắng tạo một cái gì đó trong R.
Steven D


4

Miller là một công cụ hay khác để thao tác dữ liệu dựa trên tên, bao gồm CSV (có tiêu đề). Để trích xuất cột đầu tiên của tệp CSV, mà không cần quan tâm đến tên của nó, bạn sẽ làm một cái gì đó như

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

Miller rất ấn tượng. Tôi muốn so sánh nó với awk, nhưng nhận thức cao về DSV.
Derek Mahar

3

Hoặc, bạn có thể thử một số phép thuật awk . Tuy nhiên, tôi không phải là người dùng awk tốt và không thể xác nhận điều này sẽ hoạt động tốt và cách thực hiện.


9
Đây là một công cụ phân tích cú pháp CSV mà tôi đã sử dụng một thời gian trước .. Có vẻ như chúng tôi đã nghĩ rất rõ ... lorance.freeshell.org/csv
Peter.O



2

hãy thử "csvtool" gói này, công cụ dòng lệnh tiện dụng để xử lý tệp CSV


1
Đã được đề cập, với nhiều chi tiết hơn ...
jasonwryan

2

Cissy cũng sẽ thực hiện xử lý csv dòng lệnh. Nó được viết bằng C (nhỏ / nhẹ) với các gói vòng / phút và deb cho hầu hết các bản phát hành.

Sử dụng ví dụ:

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

hoặc là

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

hoặc là

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

1

Ngoài ra còn có thư viện Curry để đọc / ghi tệp ở định dạng CSV : CSV .


2
Bạn có phiền khi đăng một số mã mẫu, như câu trả lời Perl, Python và R không? (Đặc biệt vì Curry không phải là ngôn ngữ kịch bản unix thông thường.)
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: Vâng, bạn nói đúng, tôi nên đăng một số mã mẫu để làm cho câu trả lời tốt hơn. Tôi sẽ làm điều này trong một thời gian.
imz - Ivan Zakharyaschev



1

Một trong những công cụ tốt nhất là Miller ( http://johnkerl.org/miller/doc/index.html ). Nó giống như awk, sed, cắt, tham gia và sắp xếp cho dữ liệu được lập chỉ mục tên như CSV, TSV và JSON dạng bảng.

Trong ví dụ

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

mang đến cho bạn

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

Nếu bạn muốn có TSV

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

cung cấp cho bạn (có thể xóa tiêu đề)

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

Nếu bạn muốn cột đầu tiên và thứ ba, thay đổi thứ tự của họ

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

mang đến cho bạn

 34.5,"this, is the first entry"

1

Nếu bạn muốn có một công cụ trực quan / tương tác trong thiết bị đầu cuối, tôi hoàn toàn khuyên bạn nên VisiData.

nhập mô tả hình ảnh ở đây

Nó có các bảng tần số (hiển thị ở trên), trục, tan chảy, biểu đồ phân tán, lọc / tính toán bằng Python và hơn thế nữa.

Bạn có thể truyền các tập tin csv như vậy

vd hello.csv

Có những lựa chọn cụ thể csv: --csv-dialect, --csv-delimiter, --csv-quotechar, và --csv-skipinitialspacecho tinh chỉnh xử lý các tập tin csv.


0

Một giải pháp 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.