कुशल रूप से सॉर्ट की गई फ़ाइल खोजें


12

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

कुछ Googling ने ध्वज के lookसाथ कमांड का खुलासा किया -bजो बाइनरी खोज एल्गोरिथ्म का उपयोग करके दिए गए उपसर्ग के साथ शुरुआत करने वाले सभी तारों का पता लगाने और आउटपुट करने का वादा करता है। दुर्भाग्य से, यह सही ढंग से काम नहीं करता है और स्ट्रिंग के लिए अशक्त परिणाम देता है जो मुझे पता है कि फ़ाइल में हैं (वे ठीक से बराबर grepखोज द्वारा वापस आ गए हैं)।

क्या किसी को इस फाइल को कुशलता से खोजने के लिए किसी अन्य उपयोगिता या रणनीति का पता है?


शीर्ष उत्तर गलत छँटाई को बताता है: तथ्य यह है कि आपको इसके साथ सॉर्ट करना है: LC_COLLATE = C सॉर्ट- lookकमांड को सही ढंग से कार्य करने के लिए, क्योंकि लगता है कि लोकेल को अनदेखा किया गया है और सी का उपयोग करता है जैसे हार्डकोडिंग को सॉर्ट करना, मैंने एक बग नहीं खोला है इस भ्रामक व्यवहार के कारण: Bugzilla.kernel.org/show_bug.cgi?id=198011
Sur3

look -bमेरे लिए एक त्रुटि के साथ विफल रहा File too large। मुझे लगता है कि यह पूरी बात को स्मृति में पढ़ने की कोशिश कर रहा है।
ब्रायन मिंटन

जवाबों:


9

grepऔर इसके बीच एक आवश्यक अंतर है look:

जब तक स्पष्ट रूप से अन्यथा नहीं कहा जाता है, grepलाइनों के भीतर भी कहीं न कहीं पैटर्न मिलेगा। के लिए lookमैनपेज कहता है:

देखो - प्रदर्शन लाइनें एक स्ट्रिंग के साथ शुरू होती हैं

मैं lookबहुत बार उपयोग नहीं कर रहा हूं , लेकिन यह एक तुच्छ उदाहरण पर ठीक काम करता है जो मैंने अभी कोशिश की थी।


1
मुझे जिस फ़ाइल को खोजना है, उसकी लगभग 110,000,000 लाइनें हैं। अगर मुझे egrep "^TEST" sortedlist.txt | wc -l 41,289 परिणाम मिलते हैं। हालांकि समतुल्य lookआदेश, look -b TEST sortedlist.txt | wc -lकेवल 1995 परिणाम देता है। मैं लगभग आश्चर्य है कि अगर वहाँ एक बग है look
मैट

1
@Matt शायद lookफ़ाइल को सॉर्ट करने के लिए आपके द्वारा उपयोग किए जाने वाले प्रोग्राम की तुलना में विभिन्न कोलाज सेटिंग्स का उपयोग कर रहा है।
कैस्परड

4

शायद थोड़ा देर से जवाब:

Sgrep आपकी मदद करेगा।

Sgrep (सॉर्ट किए गए grep) एक खोज कुंजी से मेल खाने वाली लाइनों के लिए सॉर्ट की गई इनपुट फ़ाइलों को खोजता है और मिलान लाइनों को आउटपुट करता है। बड़ी फ़ाइलों की खोज करते समय sgrep पारंपरिक यूनिक्स grep की तुलना में बहुत तेज़ है, लेकिन महत्वपूर्ण प्रतिबंधों के साथ।

  • सभी इनपुट फ़ाइलों को नियमित फ़ाइलों को क्रमबद्ध किया जाना चाहिए।
  • सॉर्ट कुंजी लाइन की शुरुआत में शुरू होनी चाहिए।
  • खोज कुंजी लाइन की शुरुआत में ही मेल खाती है।
  • कोई नियमित अभिव्यक्ति समर्थन नहीं।

आप यहां स्रोत डाउनलोड कर सकते हैं: https://sourceforge.net/projects/sgrep/?source=typ_redirect

और यहां दस्तावेज: http://sgrep.sourceforge.net/

दूसरा रास्ता:

मुझे नहीं पता कि फ़ाइल कितनी बड़ी है। फिर भी आपको समानांतर प्रयास करना चाहिए:

/programming/9066609/fastest-possible-grep

मैं हमेशा फाइलों के साथ grep करता हूं जो आकार> 100GB है, यह अच्छी तरह से काम करता है।


2
क्या यह पहले से ही askubuntu.com/a/701237/158442 पर नहीं है ?
मुरु

हां, मैं डाउनलोड लिंक
भरता हूं

यदि यह सब है, तो आपको एक नया उत्तर पोस्ट करने के बजाय उस पोस्ट को संपादित करना चाहिए ।
मूरू

उस पोस्ट की सिफारिश की: sudo apt-get install sgrep sgrep पाने के लिए, बंटू रिपॉजिटरी में sgrep वास्तव में यह sgrep नहीं है, मुझे यकीन नहीं है कि यह एक ही बात है।
मेमोरीबॉक्स

0

आप फ़ाइल को टुकड़ों में रख सकते हैं और फिर अपने इच्छित टुकड़े को प्राप्त कर सकते हैं:

for line in $(cat /usr/share/dict/american-english | tr '[:upper:]' '[:lower:]' | sort | uniq)
do
    prefix=$(echo $line | md5sum - | cut -c 1-2)
    mkdir -p $prefix
    echo $line | gzip >> $prefix/subwords
done

तब लुकअप ऐसा दिखेगा:

    prefix=$(echo $word | md5sum - | cut -c 1-2)
    zgrep -m 1 -w word $prefix/subwords

यह दो काम करता है:

  1. संकुचित फ़ाइलों को पढ़ें और लिखें। डिस्क के बजाय (बहुत तेज़) डिस्क पर लोड डालना बहुत धीमा है (बहुत धीमा)
  2. लगभग समान वितरण प्राप्त करने के लिए हैश चीजें, आप एक छोटे या लंबे समय तक हैश का उपयोग कर सकते हैं जैसा कि आप प्रत्येक टुकड़े के आकार को कम करने के लिए करना चाहते हैं (लेकिन यदि आप करते हैं तो मैं नेस्टेड उपखंडों का उपयोग करने की सलाह दूंगा)

0

sgrep आपके लिए काम कर सकता है:

sudo apt-get install sgrep
sgrep -l '"needle"' haystack.txt

प्रोजेक्ट पेज http://sgrep.sourceforge.net/ कहता है:

Sgrep एक द्विआधारी खोज एल्गोरिथ्म का उपयोग करता है, जो बहुत तेज़ है, लेकिन इसके लिए सॉर्ट किए गए इनपुट की आवश्यकता होती है।

सम्मिलन के लिए, हालांकि, मुझे लगता है कि डेटाबेस का उपयोग करने से बेहतर कोई उपाय नहीं है: /programming/10658380/shell-one-liner-to-add-a-line-to-a-sorted-file/ 33859372 # 33859372


3
sgrepउबंटू खजाने में वास्तव में है इस sgrep है, जो "एक संरचित पैटर्न के लिए एक फ़ाइल खोज" के लिए बनाया गया और द्विआधारी खोज के साथ कोई संबंध नहीं है है।
ingomueller.net

0

यदि आप इसे वास्तव में तेज़ चाहते हैं (O (1) तेज़) तो आप देखने के लिए हैश सेट बना सकते हैं। मुझे एक कार्यान्वयन नहीं मिला, जो मुझे एक फ़ाइल में पूर्व-निर्मित हैश सेट को संग्रहीत करने और पूरी फ़ाइल को मेमोरी में पढ़ने के बिना इसकी जांच करने देगा, इसलिए मैंने अपना स्वयं का रोल किया

हैश सेट ( -b/ --build) बनाएँ :

./hashset.py --build string-list.txt strings.pyhashset

जांच सेट हैश ( -p/ --probe):

./hashset.py --probe strings.pyhashset \
    'Is this string in my string list?' 'What about this one?'

... या मानक इनपुट पर देखने के लिए स्ट्रिंग के साथ:

printf '%s\n' 'Is this string in my string list?' 'What about this one?' |
./hashset.py --probe strings.pyhashset

यदि आप केवल बाहर निकलने की स्थिति में रुचि रखते हैं, तो आप / विकल्प के --probeसाथ आउटपुट को शांत कर सकते हैं:-q--quiet

if ./hashset.py --quiet --probe strings.pyhashset ...; then
    echo 'Found'
else
    echo 'Not found'
fi

अधिक विकल्पों के लिए उपयोग विवरण को -h/ --helpविकल्प या साथ READMEफाइल के माध्यम से सुलभ देखें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.