Xóa các dòng trùng lặp khỏi tệp văn bản rất lớn [trùng lặp]


2

Câu hỏi này đã có câu trả lời ở đây:

Tôi có tệp văn bản rất lớn (& gt; 50 GB), nhưng hầu hết các dòng đều trùng lặp, vì vậy tôi muốn xóa chúng. Có cách nào để xóa các dòng trùng lặp khỏi tệp và xử lý tệp & gt; 2GB? Bởi vì mọi phương pháp tôi tìm thấy cho đến bây giờ chỉ có thể hoạt động trên các tệp nhỏ.


Công cụ tốt nhất cho công việc này là công cụ bạn tự viết.
Ramhound

Viết kịch bản Python tốt hơn, có thể làm điều đó. HĐH gì? Python có thể làm trên bất kỳ.
RProgram

Xin vui lòng luôn luôn bao gồm hệ điều hành của bạn. Các giải pháp rất thường phụ thuộc vào Hệ điều hành đang được sử dụng. Bạn đang sử dụng Windows, Linux, Unix, OSX, BSD? Phiên bản nào?
terdon

Bạn đã thử những công cụ nào?
jftuga

Bạn đã thử sắp xếp -u trên tập tin lớn? Nó có thể hoạt động, bạn biết đấy ... nếu không, bạn cũng có thể vá nó thay vì bắt đầu một chương trình C từ đầu.
user2987828

Câu trả lời:


4

Giả sử tất cả các dòng ngắn hơn 7kB và bạn đã cài đặt bash, dd, tail, head, sed và sort từ cygwin / unix:

{
  i=0
  while LANG= dd 2>/dev/null bs=1024 skip=${i}000 if=large_text_file count=1021 \
  | LANG= sed -e '1d' -e '$d'  | LANG= sort -u ;
  do
    i=$((1+$i))
  done
  LANG= dd 2>/dev/null bs=1024 skip=${i}000 if=large_text_file count=1021 \
  | LANG= tail -n 1
  LANG= head -n 1 large_text_file
} | LANG= sort -u > your_result

Thao tác này chia tệp thành từng phần 1024000 byte và thêm 3 * 7 * 1024 byte ("21" trong 1021 ) từ đoạn tiếp theo. Vì các bộ phận có thể cắt một dòng, đầu tiên ( 1d ) và cuối cùng ( $d ) dòng của mỗi khối bị phá hủy ( sed ).

Vì vậy, để bù lại, một cái gì đó chứa đoạn cuối cùng được trích xuất lại và chỉ dòng cuối cùng của nó được giữ lại (đuôi -n 1), và dòng đầu tiên cũng được trích xuất lại (đầu -n 1).

Khi vòng lặp thất bại, đoạn cuối cùng đã được trích xuất.

sort -u có thể được xem như một máy nén, nhưng nó chỉ sắp xếp đầu vào của nó sau đó bỏ qua các bản sao. "Sắp xếp" đầu tiên nén tất cả các khối. Thư hai sort nén lại các phần nối của tất cả các khối này (và giây đó sort đã bị thiếu từ mã trên kể từ lần chỉnh sửa thứ ba, xin lỗi).

Bạn đã nói tập tin văn bản, nhưng dù sao tôi cũng giả sử LANG= (nhận được tất cả cũng nhanh hơn).


Đây có phải là để chạy trên một vỏ? Vỏ nào? for i=`seq 50000` Tôi sẽ không làm việc trên bất kỳ vỏ * nix nào, ý tôi là for i in $(seq 50000)?. Bạn cũng có thể thêm một số lời giải thích về những gì bạn đang làm? Bạn đang sử dụng một vài thủ thuật tiện lợi ở đây nhưng đừng nói với OP chúng là gì hoặc cách chúng hoạt động.
terdon

Chỉ cần thực hiện điều này trên GNU bash, phiên bản 4.2.25 (1) -release (x86_64-pc-linux-gnu): cho tôi trong /usr/bin/seq 4; làm vang $ i; làm xong
user2987828

Vâng, điều đó sẽ làm việc, nhưng không phải là những gì bạn đã đăng. for i=`seq 4` không tương đương với for i in `seq 4`. Tôi đã chỉnh sửa câu trả lời của bạn bây giờ mà tôi biết đó không phải là một số tính năng lạ của windows shell. Đây thực sự sẽ là một câu trả lời tuyệt vời nếu bạn thêm một lời giải thích về những gì nó làm. Bí quyết đọc tệp theo khối để loại bỏ một số bản sao trước khi sắp xếp để loại bỏ phần còn lại là một ý tưởng tuyệt vời nhưng rất khó hiểu nếu bạn không trò chuyện với các công cụ bạn sử dụng.
terdon

Điều này sẽ chỉ loại bỏ các bản sao kết thúc trong cùng một đoạn.
Loren Pechtel

Tôi vừa đặt lại cái thứ hai sort đó là và đã được ghi lại ở cuối bài viết của tôi, đó là loại bỏ các bản sao từ các phần khác nhau. Đây là một lỗi do chỉnh sửa trước đây của tôi, xin lỗi: nó chỉ xóa các bản sao kết thúc trong cùng một đoạn, như được chỉ ra bởi Loren Pechtel.
user2987828

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.