2016-11-26 5 views
7

में फ़िट होने के लिए बहुत बड़ी है, मुझे एक फ़ाइल मिली है जो स्मृति में फिट होने के लिए बहुत बड़ी है। shuf रैम में चल रहा है, और sort -R शफल नहीं होता है (समान रेखाएं एक दूसरे के बगल में समाप्त होती हैं; मुझे सभी लाइनों को शफल करने की आवश्यकता होती है)। क्या मेरे अपने समाधान को घुमाने के अलावा कोई विकल्प है?बैश - एक फ़ाइल को घुमाएं जो मेमोरी

उत्तर

7

decorate-sort-undecorate पैटर्न का एक रूप का उपयोग करते हुए और awk आप की तरह कुछ कर सकते हैं: एक फ़ाइल के लिए

$ seq 10 | awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8- 
8 
5 
1 
9 
6 
3 
7 
2 
10 
4 

, आप क्या करेंगे:

$ awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' SORTED.TXT | sort -n | cut -c8- > SHUFFLED.TXT 

या पाइपलाइन की शुरुआत में cat फ़ाइल।

यह 000000 और 999999 समावेशी (सजाने) के बीच यादृच्छिक संख्याओं का एक स्तंभ उत्पन्न करके काम करता है; उस कॉलम (सॉर्ट) पर सॉर्टिंग; फिर कॉलम को हटा देना (अनिश्चित)। यह उन प्लेटफॉर्म पर काम करना चाहिए जहां लेक्सिकोग्राफिक सॉर्टिंग के लिए अग्रणी शून्य के साथ कॉलम उत्पन्न करके क्रमिक संख्या को समझ में नहीं आता है।

आप अगर वांछित, कि यादृच्छिकीकरण बढ़ा सकते हैं, कई मायनों में:

  1. अपने प्लेटफ़ॉर्म के sort संख्यात्मक मानों को समझ लेता है (इसे POSIX, जीएनयू और बीएसडी करते हैं) आप awk 'BEGIN{srand();} {printf "%0.15f\t%s\n", rand(), $0;}' FILE.TXT | sort -n | cut -f 2- कर सकते हैं के लिए एक के पास डबल नाव का उपयोग करने के यादृच्छिक प्रतिनिधित्व। awk 'BEGIN{srand();} {printf "%06d%06d\t%s\n", rand()*1000000,rand()*1000000, $0;}' FILE.TXT | sort -n | cut -f 2- जो यादृच्छिकीकरण का एक समग्र 12 अंक देता है:

  2. आप एक कोषगत प्रकार तक ही सीमित रहे हैं, तो सिर्फ rand करने के लिए दो कॉल एक स्तंभ में की तरह तो गठबंधन।

+0

अच्छा बहु-टेराबाइट पाठ फ़ाइलों फेरबदल के लिए एक अर्ध फेरबदल एल्गोरिथ्म लागू करता है। क्योंकि स्मृति 'फिट (जीएनयू संस्करण, किसी भी तरह) में फिट होने से बड़ी सामग्री को संसाधित करने के लिए' सॉर्ट 'कई फ़ाइलों में विभाजित होता है, यह वास्तव में काम करना चाहिए। –

+0

+1 - अच्छा विचार। ध्यान दें कि चूंकि 'सॉर्ट' एक स्थिर प्रकार का प्रदर्शन करता है, यह 100% सही शफल नहीं होगा: यदि लाइन ए इनपुट में लाइन बी से पहले आता है, तो यह दृष्टिकोण आउटपुट में लाइन बी से पहले लाइन ए डालने की संभावना अधिक है। इसे ठीक करने के लिए, आप 'seq 10' जैसे कुछ लिखकर नंबरिंग और शफलिंग को उलटा कर सकते हैं grep -n '' | सॉर्ट -आर | कट-डी: -एफ 2-'इसके बजाए। (लेकिन उस बदलाव के बिना भी, मुझे लगता है कि यह शायद ठीक है: मुझे लगता है कि यह एक यादृच्छिक क्रम के करीब होना चाहिए।) – ruakh

+0

@ruakh: धन्यवाद। आप सही हैं - स्थिर प्रकार होने के कारण 'क्रमबद्ध' होने के कारण क्रम को बनाए रखने की थोड़ी प्रवृत्ति होती है। इसमें 0 और 1000000 के बीच यादृच्छिक अंक हैं, इसलिए यह केवल पंक्ति में दो पंक्तियों पर एक ही यादृच्छिक संख्या के साथ एक मुद्दा होगा। इसे और अधिक यादृच्छिक बनाने का एक और तरीका यादृच्छिक अंकों के अधिक अंक या दूसरे कॉलम को जोड़ना है। – dawg

3

गिनती रेखाएं (wc -l) और यादृच्छिक क्रम में लाइन संख्याओं से संबंधित संख्याओं की एक सूची उत्पन्न करें - शायद एक अस्थायी फ़ाइल में संख्याओं की एक सूची उत्पन्न करके (/tmp/ का उपयोग करें, जो आम तौर पर रैम में है, और इस प्रकार अपेक्षाकृत तेज़ है)। फिर शफ़ल संख्याओं के क्रम में प्रत्येक फ़ाइल से संबंधित पंक्ति को लक्ष्य फ़ाइल में कॉपी करें।

फ़ाइल में न्यूलाइन की तलाश करने की मात्रा के कारण यह समय-अक्षम होगा, लेकिन यह लगभग किसी भी आकार की फ़ाइल पर काम करेगा।

0

के बारे में कैसे: perl <large-input-file -lne 'print rand(), "\t", $_' | sort | perl -lpe 's/^.*?\t//' >shuffled-output-file

0

तो फ़ाइल क्या स्मृति में फिट कर सकते हैं की भयावहता के कुछ आदेशों के भीतर है, एक ही विकल्प बेतरतीब ढंग से, (जैसे कि) 1000 अस्थायी फ़ाइलों के बीच लाइनों वितरित तो उन फ़ाइलों में से प्रत्येक शफ़ल और परिणाम को श्रेणीबद्ध करने के लिए है :

perl -we ' my $NUM_FILES = 1000; 
      my @fhs; 
      for (my $i = 0; $i < $NUM_FILES; ++$i) { 
      open $fh[$i], "> tmp.$i.txt" 
       or die "Error opening tmp.$i.txt: $!"; 
      } 
      while (<>) { 
      $fh[int rand $NUM_FILES]->print($_); 
      } 
      foreach my $fh (@fhs) { 
      close $fh; 
      } 
     ' < input.txt \ 
&& \ 
for tmp_file in tmp.*.txt ; do 
    shuf ./"$tmp_file" && rm ./"$tmp_file" 
done > output.txt 

(बेशक, वहाँ अस्थायी फ़ाइलों — के आकार में कुछ बदलाव के वे सब नहीं होगा बिल्कुल एक हज़ारवां मूल फ़ाइल — के आकार, इसलिए यदि आप इस दृष्टिकोण का उपयोग किया जाएगा , आपको अपने आप को कुछ और पक्ष के पक्ष में कुछ बफर देना होगा, छोटी फाइलें।)

+0

प्रारंभिक गलतफहमी क्षमा करें - मुझे आशा है कि डाउनवॉटर ने मेरे दोषपूर्ण विश्लेषण पर भरोसा नहीं किया है। यह एक बिल्कुल उचित दृष्टिकोण है। –

+0

@ चार्ल्स डफी: कोई चिंता नहीं। मैं * अनुमान लगा रहा हूं * डाउनवॉटर वास्तव में एल 'एल था। (और यदि नहीं, तो अब मुझे लगता है कि दाग का जवाब मेरा से बेहतर दृष्टिकोण है, इसलिए मैं इस उत्तर से बहुत जुड़ा हुआ नहीं हूं। :- पी) – ruakh

संबंधित मुद्दे