2013-06-01 22 views
10

Tôi có khoảng 350 tệp văn bản (và mỗi tệp là khoảng 75MB). Tôi đang cố gắng kết hợp tất cả các tệp và xóa các mục trùng lặp. Các tập tin có định dạng sau:kết hợp nhiều tệp văn bản và xóa các bản sao

ip1,dns1 
ip2,dns2 
... 

Tôi đã viết một kịch bản nhỏ để làm điều này

#!/bin/bash 
for file in data/* 
do 
    cat "$file" >> dnsFull 
done 
sort dnsFull > dnsSorted 
uniq dnsSorted dnsOut 
rm dnsFull dnsSorted 

tôi đang làm chế biến này thường xuyên và đã tự hỏi nếu có bất cứ điều gì tôi có thể làm để cải thiện việc xử lý lần sau khi tôi chạy nó. Tôi mở cho bất kỳ ngôn ngữ lập trình và đề xuất nào. Cảm ơn!

+0

bạn cũng có thể cung cấp sắp xếp -ma thử -> nó sẽ sắp xếp các tệp riêng lẻ và hợp nhất chúng cho phù hợp do đó nên tiết kiệm khá nhiều thời gian .... tùy chọn -m là espl có sẵn cho kịch bản như thế này ... tức là sắp xếp -m file * | uniq -u – nsd

Trả lời

30

Trước hết, bạn không sử dụng toàn bộ sức mạnh của cat. Vòng lặp có thể được thay thế bằng chỉ

cat data/* > dnsFull 

giả sử tập tin đó là ban đầu trống rỗng.

Sau đó, có tất cả các tệp tạm thời đó buộc các chương trình chờ đĩa cứng (thường là các phần chậm nhất trong các hệ thống máy tính hiện đại). Sử dụng một đường ống dẫn:

cat data/* | sort | uniq > dnsOut 

này vẫn còn lãng phí kể từ khi một mình sort có thể làm những gì bạn đang sử dụng catuniq cho; toàn bộ kịch bản có thể được thay thế bằng

sort -u data/* > dnsOut 

Nếu điều này vẫn không đủ nhanh, sau đó nhận ra phân loại mà mất O (n lg n) thời gian trong khi pc có thể được thực hiện trong thời gian tuyến tính với AWK:

awk '{if (!a[$0]++) print}' data/* > dnsOut 
+0

Rất tốt, cảm ơn. – drk

+5

Lưu ý rằng awk cuối cùng có thể được đơn giản hóa thành 'awk'! [Dữ liệu $ 0] ++ '/ * ' –

+1

Tôi đã xóa câu trả lời perl vì 350 * 75MB = hơn 26GB - sắp xếp trong bộ nhớ (như awk) có thể gây ra quá nhiều bộ nhớ hoán đổi. – jm666

Các vấn đề liên quan