समय के साथ सशक्त डुप्लिकेट खोजने का तेज़ तरीका

AIX के साथ PERL के बिना एक मशीन में मुझे रिकॉर्ड्स फ़िल्टर करने की आवश्यकता है जिसे डुप्लिकेट माना जाएगा यदि उनके पास एक ही आईडी है और यदि वे चार घंटे की अवधि के बीच पंजीकृत हैं।

मैंने AWK का उपयोग करके इस फ़िल्टर को कार्यान्वित किया और बहुत अच्छी तरह से काम किया लेकिन मुझे एक समाधान की आवश्यकता बहुत तेज है:

# Generar lista de Duplicados
awk 'BEGIN {
FS="," 
}
/OK/ { 
    old[$8] = f[$8];
    f[$8] = mktime($4, $3, $2, $5, $6, $7); 
    x[$8]++;
}
/OK/ && x[$8]>1 && f[$8]-old[$8] 


Any suggestions? Are there ways to improve the environment (preloading the file or someting like that)?
The input file is already sorted.
With the corrections suggested by jj33 I made a new version with better treatment of dates, still maintaining a low profile for incorporating more operations: awk 'BEGIN { FS=","; SECSPERMINUTE=60; SECSPERHOUR=3600; SECSPERDAY=86400; split("0 31 59 90 120 151 181 212 243 273 304 334", DAYSTOMONTH, " "); split("0 366 731 1096 1461 1827 2192 2557 2922 3288 3653 4018 4383 4749 5114 5479 5844 6210 6575 6940 7305", DAYSTOYEAR, " "); } /OK/ { old[$8] = f[$8]; f[$8] = mktime($4, $3, $2, $5, $6, $7); x[$8]++; } /OK/ && x[$8]>1 && f[$8]-old[$8] 2 ) && ( ((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0) ) ) { d2m = d2m + 1; } d2y = DAYSTOYEAR[ y - 1999 ]; return ss + (mm*SECSPERMINUTE) + (hh*SECSPEROUR) + (d*SECSPERDAY) + (d2m*SECSPERDAY) + (d2y*SECSPERDAY); } '
0
ro fr bn

6 उत्तर

यदि आपकी डेटा फ़ाइल में आपके सभी रिकॉर्ड हैं (यानी इसमें ऐसे रिकॉर्ड शामिल हैं जिनमें फ़ाइल के भीतर डुप्लिकेट आईडी नहीं हैं) तो आप इसे प्री-प्रोसेस कर सकते हैं और एक फ़ाइल तैयार कर सकते हैं जिसमें केवल डुप्लिकेट (आईडी) वाले रिकॉर्ड हों।

यदि ऐसा मामला है जो फ़ाइल के आकार को कम करेगा तो आपको अपने एडब्ल्यूके प्रोग्राम के साथ प्रक्रिया करने की आवश्यकता है।

0
जोड़ा

कई यूनिक्स पर, आप किसी विशेष कॉलम या फ़ील्ड द्वारा सॉर्ट करने के लिए सॉर्ट कर सकते हैं। तो आईडी द्वारा फ़ाइल को सॉर्ट करके, और फिर तिथि तक, अब आपको प्रत्येक आईडी को आखिरी बार देखा जाने पर सहयोगी सरणी को रखने की आवश्यकता नहीं है। फ़ाइल के क्रम में सभी संदर्भ है।

मेरे मैक पर, जिसमें जीएनयू सॉर्ट है, यह है:

sort -k 8 < input.txt > output.txt

आईडी फ़ील्ड को सॉर्ट करने के लिए। आप इसके बजाय एक दूसरे फ़ील्ड को भी क्रमबद्ध कर सकते हैं (उदाहरण के लिए) 8,3, लेकिन केवल 2 फ़ील्ड। तो फ़ाइल में एक यूनिक्स-स्टाइल टाइम_टी टाइमस्टैम्प एक बुरा विचार नहीं हो सकता है - यह सॉर्ट करना आसान है, और आपको उन सभी दिनांक गणनाओं को बचाता है। साथ ही, (कम से कम जीएनयू अजीब में), एक mktime फ़ंक्शन है जो घटकों से आपके लिए time_t बनाता है।

0
जोड़ा

इनपुट फ़ाइल कैसे क्रमबद्ध है? जैसे, बिल्ली फ़ाइल | सॉर्ट करें, या एक विशिष्ट फ़ील्ड, या एकाधिक फ़ील्ड के माध्यम से सॉर्ट किया गया है? यदि एकाधिक फ़ील्ड, कौन से फ़ील्ड और किस ऑर्डर? ऐसा लगता है कि घंटे के क्षेत्र 24 घंटे की घड़ी हैं, 12 नहीं, है ना? क्या सभी दिनांक / समय फ़ील्ड शून्य-गद्देदार हैं (9 बजे "9" या "0 9" होंगे?)

खाता प्रदर्शन करने के बिना ऐसा लगता है कि आपके कोड में महीने की सीमाओं के साथ समस्याएं हैं क्योंकि यह मानता है कि सभी महीने 30 दिन लंबे हैं। दो तिथियां 2008-05-31 / 12: 00: 00 और 2008-06-01: 12: 00: 00 लें। वे 24 घंटे अलग हैं लेकिन आपका कोड दोनों के लिए एक ही समय कोड उत्पन्न करता है (63339 9 6 9 600)

0
जोड़ा

मुझे लगता है कि आपको लीप साल पर विचार करना होगा। मैंने गणित नहीं किया, लेकिन मुझे लगता है कि एक लीप वर्ष के दौरान, फीब के लिए 28 दिनों के हार्ड कोड के साथ, 2/2 9 पर दोपहर की तुलना और 3/1 पर दोपहर की तुलना में पहले के समान डुप्लिकेट टाइम स्टैम्प होगा । हालांकि ऐसा लगता है कि आपने इसे इस तरह लागू नहीं किया है। जिस तरह से आपने इसे कार्यान्वित किया, मुझे लगता है कि आपको अभी भी समस्या है, लेकिन यह 12/31 डॉलर की लीपियर और 1/1 डॉलर लीपियर + 1 की तिथियों के बीच है।

मुझे लगता है कि यदि आपके कोड को समय क्षेत्र को संभालने के लिए समय कोड को संभालना है तो आपको समय परिवर्तन के दौरान कुछ टकराव भी हो सकते हैं।

फ़ाइल वास्तव में किसी भी उपयोगी तरीके से क्रमबद्ध नहीं लगती है। मुझे लगता है कि फ़ील्ड $ 1 किसी प्रकार की स्थिति है ("ठीक है" आप जांच रहे हैं)। तो इसे रिकॉर्ड स्थिति द्वारा क्रमबद्ध किया जाता है, फिर दिन, फिर माह, वर्ष, घंटे, मिनट, सेकंड्स द्वारा क्रमबद्ध किया जाता है। अगर यह वर्ष, महीना था, तो मुझे लगता है कि वहां कुछ अनुकूलन हो सकते हैं। अभी भी हो सकता है लेकिन मेरा दिमाग अभी एक अलग दिशा में जा रहा है।

यदि लाइनों की कुल संख्या के अनुपात में डुप्लिकेट कुंजी की एक छोटी संख्या है, तो मुझे लगता है कि आपकी सबसे अच्छी शर्त फ़ाइल को कम करने के लिए है, आपकी अजीब स्क्रिप्ट केवल डुप्लिकेट कुंजी पर काम करती है (जैसे डेविड ने कहा )। आप फ़ाइल को प्रीप्रोसेस भी कर सकते हैं ताकि मौजूद केवल लाइनें / ठीक / रेखाएं हों। मुझे लगता है कि मैं इसे एक पाइपलाइन के साथ करूँगा जहां पहली अजीब स्क्रिप्ट केवल डुप्लिकेट आईडी के साथ लाइनों को प्रिंट करती है और दूसरी अजीब स्क्रिप्ट मूल रूप से उपर्युक्त है लेकिन अनुकूलित / ठीक / और ज्ञान के साथ ऑप्टिमाइज़ किया गया है कि कोई भी मुख्य उपस्थिति है नकली चाबी।

यदि आप समय से पहले जानते हैं कि सभी या अधिकतर लाइनों में दोबारा चाबियां होंगी, तो शायद यह गड़बड़ करने योग्य नहीं है। मैं बुलेट काट दूंगा और इसे सी में लिखूंगा। कोड की अधिक रेखाएं, अजीब लिपि से बहुत तेज़ हैं।

0
जोड़ा

@ AnotherHowie , मैंने सोचा कि पूरा प्रीप्रोकैसिंग हो सकता है सॉर्ट और यूनिक के साथ किया गया। समस्या यह है कि ओपी का डेटा अल्पविराम को सीमित करता है और (सोलारिस 8) यूनिक आपको किसी भी तरह से रिकॉर्ड विभाजक निर्दिष्ट करने की अनुमति नहीं देता है, इसलिए मानक यूनिक्स उपकरण का उपयोग करके प्रीप्रोकैसिंग करने का एक सुपर क्लीन तरीका नहीं था। मुझे नहीं लगता कि यह कोई तेज़ होगा इसलिए मैं सटीक विकल्पों को देखने के लिए नहीं जा रहा हूं, लेकिन आप ऐसा कुछ कर सकते हैं:

cut -d, -f8 outfile.txt

यह बहुत अच्छा नहीं है क्योंकि यह डुप्लिकेट कुंजी वाली प्रत्येक पंक्ति के लिए grep निष्पादित करता है। आप grep को फ़ीड करने के लिए शायद एक एकल regexp में uniq आउटपुट को मालिश कर सकते हैं, लेकिन लाभ केवल तभी ज्ञात होगा जब ओपी पोस्ट फ़ाइल में कुल पंक्तियों के लिए संदिग्ध डुप्लिकेट कुंजी वाली लाइनों के अपेक्षित अनुपात की अपेक्षा करता है।

0
जोड़ा

यह एक वास्तविक डेटाबेस के लिए नौकरी की तरह लगता है। SQLite की तरह कुछ भी शायद आपको उचित रूप से अच्छी तरह से मदद कर सकता है। मुझे लगता है कि बड़ी समस्या "4 घंटे के भीतर" की आपकी परिभाषा है। यह एक स्लाइडिंग विंडो समस्या है, जिसका अर्थ है कि आप केवल 4 घंटे सेगमेंट तक सभी डेटा को माप नहीं सकते हैं ... आपको हर दूसरे तत्व के लिए अलग-अलग "आस-पास" तत्वों की गणना करना होगा। ओह।

0
जोड़ा