Giới thiệu lại một tệp CSV lớn


11

Tôi đã xem qua các câu trả lời trong chủ đề hữu ích này , nhưng vấn đề của tôi dường như đủ khác để tôi không thể nghĩ ra câu trả lời hay (ít nhất là với sed).

Tôi có một tệp CSV lớn (hơn 200 GB) với các hàng trông như sau:

<alphanumerical_identifier>,<number>

nơi <alphanumerical_identifier>duy nhất trên toàn bộ tập tin. Tôi muốn tạo một tệp riêng thay thế cột đầu tiên bằng một chỉ mục , nghĩa là

<index>,<number>

để chúng tôi nhận được:

1, <number>
2, <number>
3, <number>

Có thể awktạo một chỉ mục tăng mà không tải tập tin đầy đủ trong bộ nhớ?

Vì chỉ số tăng đơn điệu, có thể tốt hơn nếu chỉ bỏ chỉ số. Giải pháp cho điều đó có khác không?, Tức là:

<number>
<number>
<number>

Tôi không chắc về tính khả thi của giải pháp này. Nhưng làm thế nào về việc chỉ tạo nhiều số như trong tệp CSV trong một tệp riêng biệt và sau đó chỉ nối thêm cột thứ hai của tệp CSV vào tệp đó?
Ramesh

@Ramesh Điều đó là hoàn toàn tốt miễn là đầu ra là chính xác.
Amelio Vazquez-Reina

2
Tôi nghi ngờ tôi đang hiểu nhầm điều gì đó; nếu không, awk -F, '{print ++n, $2}'sẽ làm việc. Hoặc awk -F, '{print $2}'cho biến thể thứ hai.
G-Man nói 'Phục hồi Monica'

2
@ G-Man, có lẽ nó mặc dù FNRsẽ phục vụ tốt như++n
iruvar

1
Tôi đã kiểm tra ba lần rằng bạn thực sự có thể thoát khỏi Định danh Uniq đó ... tại sao không thêm cột đầu tiên (thứ 3) với chỉ mục, nhưng vẫn giữ mã định danh? không phải là định danh được sử dụng bất cứ nơi nào khác?
Olivier Dulac

Câu trả lời:


13

Không phải gần một thiết bị đầu cuối để kiểm tra, nhưng làm thế nào về lệnh oft bị bỏ qua nl? Cái gì đó như:

cut -f 2 -d , original.csv | nl -w 1 -p -s , > numbered.csv


1
PS: Một tệp CSV 200 GB ? Ồ, và tôi nghĩ rằng làm việc với Cơ sở dữ liệu số được chuyển ở Bắc Mỹ dưới dạng CSV (một vài DVD) là rất lớn!
giám mục

1
Nó hoạt động, mặc dù có một khoảng trống lớn sau số. Tôi sẽ thay thế nó bằng:cut -d, -f 2- /tmp/aa | nl -w 1 -p -s ,
Ángel

@Angel: Cảm ơn, đã cập nhật câu trả lời của tôi để sử dụng tùy chọn độ rộng -w 1thay vì đánh số trái.
giám mục

Cảm ơn @bishop - Tên tệp đầu vào và đầu ra đi đâu?
Amelio Vazquez-Reina

1
@ user815423426 Có, cutlệnh trước ký hiệu ống ( |) sẽ chỉ cung cấp cho bạn cột thứ hai, có hiệu quả là có các số dòng ẩn.
giám mục

7

Dưới đây là một vài cách tiếp cận, nhưng không có cách nào sẽ tiếp cận tốc độ của giải pháp cutnlgiải pháp ở trên:

  1. ôi

    awk -F, '{$1=NR;print $1","$2;}' file.csv > newfile.csv
  2. Perl

    perl -pe 's/[^,]+/$./' file.csv > newfile.csv

    hoặc là

    perl -F, -ane '$F[0]=$.; print join ",", @F' file.csv
  3. Shell (nhưng tôi không khuyên dùng tệp 200G, sẽ mất nhiều năm)

    i=1; while IFS=, read foo num; do 
            printf "%d,%s\n" $((i++)) $num; 
    done < file.csv > newfile.csv

Các giải pháp trên được sắp xếp theo thứ tự tốc độ. Tôi đã thử nghiệm trên máy tính xách tay của mình và một tệp 40M và họ đã lấy (trung bình 10 lần chạy) 2.2282 (awk), 2.4555 (lần đầu tiên), 3.1825 giây (lần thứ 2) và 48.6035 giây cho vỏ. Giải pháp rất thông minh cutnlbạn đã có nhanh hơn khoảng 4 lần với 0,6078s.


Tốt đẹp, cảm ơn các số liệu thống kê! Kết quả vỏ làm tôi ngạc nhiên, phần nào. Nếu bạn thay thế printfbằng echo, thời gian có cải thiện đáng kể?
giám mục

2
Tập tin 40G được xử lý trong 2,2282 giây? Tôi có thể lấy máy tính xách tay đó ở đâu?
John B

2
@JohnB umm, vâng, xin lỗi, đó là 40 triệu, không phải G :)
terdon

Tôi thích đặt lại $1cách tiếp cận với awk. Các cutgiải pháp chắc chắn là nhanh hơn nhiều, nhưng đó là để được mong đợi vì nó không thay thế <alphanumerical_identifier>với bất cứ điều gì. Tôi nghĩ rằng awkbiến thể nhanh nhất có thể là một cái gì đó như : mawk 'BEGIN{FS=OFS=","}{$1=NR}1' file.csv > newfile.csv.
John B

@JohnB ah, vâng, tôi đoán rằng việc sử dụng OFSthay vì in rõ ràng ,sẽ nhanh hơn một chút và điều đó có thể làm tăng thêm sự khác biệt đáng kể trong tệp lớn.
terdon
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.