Có tiện ích dòng lệnh để hoán chuyển tệp csv không?


16

Đưa ra một tập tin như vậy

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

Có tiện ích dòng lệnh để hoán đổi nội dung để đầu ra xuất hiện như vậy không

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

Câu trả lời:


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

Với độ tuổi của câu hỏi này, tôi sẽ biện minh cho việc thay đổi của mình thành câu hỏi được chấp nhận: a) Câu trả lời này ngắn gọn hơn nhiều so với Gilles ' python, b) rubykhông kém phần di động hơn pythonvà c) điều này cũng cho thấy cách vượt qua đầu vào / đầu ra các tập tin. Bravo @luikore và chào mừng bạn đến với Unix & Linux. Xin vui lòng dính xung quanh.
Cory Klein

một cảnh báo, trong csv, các trường phải được trích dẫn
yosefrow

@yosefrow Không cần trích dẫn. Tôi đã kiểm tra lệnh trước khi tôi đăng câu trả lời này.
luikore

ok nên nói "may" rồi. Nó không làm việc cho tôi cho đến khi tôi trích dẫn tất cả các lĩnh vực. Có thể phải làm với nội dung dữ liệu của tôi
yosefrow

16

Phân tích cú pháp CSV không dễ dàng thực hiện chỉ với các công cụ POSIX, trừ khi bạn đang sử dụng biến thể CSV được đơn giản hóa mà không có trích dẫn (để dấu phẩy không thể xuất hiện trong một trường). Ngay cả sau đó, nhiệm vụ này dường như không dễ thực hiện với awk hoặc xử lý văn bản khác cho công cụ. Bạn có thể sử dụng Perl với Text::CSV, Python với csv, R với read.csv, Ruby với CSV , MR (Tất cả những thứ này là một phần của thư viện chuẩn của ngôn ngữ tương ứng ngoại trừ Perl.)

Ví dụ: trong 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])

11

Từ /programming//a/2776078 :

$ apt-get install csvtool

Và sau đó chuyển đổi

$ csvtool transpose input.csv > ouput.csv

Hoặc trong đường ống

$ ... | csvtool transpose - | ...

1
xinh đẹp. Chỉ có ... | csvtranspose | ...thể đánh bại điều đó, cú pháp khôn ngoan.
masterxilo

3

Một giải pháp nhanh & bẩn :

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 đại diện cho cái gì? Ngoài ra, sẽ không đơn giản hơn khi lặp qua các cột thay vì các dòng, một cái gì đó dọc theo dòngfor ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
iruvar

Lưu ý rằng điều này hoạt động cho đầu vào của OP, nhưng chỉ vì dữ liệu của họ có cùng số lượng hàng và cột, thường không phải là trường hợp.
tokland

csv có thông số kỹ thuật liên quan đến dấu ngoặc kép, tức là this "is" exampleô được mã hóa "this ""is"" example"Tôi không tin nếu giải pháp này xử lý đúng các trường hợp như vậy
Grzegorz Wierzowiecki

0

Với giới hạn được đề xuất (không trích dẫn, không có dấu phẩy nhúng), thật đơn giản trong awk (vì nó sẽ không tính đến hơn một nghìn dòng CSV.pm, 2300 dòng trong csv.rb- python chỉ có 450 dòng csv.py).

Đây là một ví dụ cho 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];
    }
}

Nhân tiện: ví dụ đã cho có thêm không gian mà OP giả định sẽ bị xóa; các ví dụ khác không đề cập đến chi tiết này.

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.