2013-02-14 35 views
6

मैं मूल रूप सेकमांड लाइन पर क्रमबद्ध आउटपुट की पहली कुछ पंक्तियों को कुशलतापूर्वक प्रिंट करने के लिए मैं किस मानक कमांड का उपयोग कर सकता हूं?

... | sort -arg1 -arg2 -... | head -n $k 

के बराबर चाहते हैं, लेकिन, मेरी समझ यह है कि तरह पूरे इनपुट से अधिक ओ (n लॉग n) जाना होगा। मेरे मामले में मैं बहुत सारे डेटा से निपट रहा हूं, इसलिए रनटाइम मेरे लिए मायने रखता है - और मेरे पास भी मेरे अस्थायी फ़ाइलों के साथ मेरे tmp/फ़ोल्डर को बहने की आदत है।

मैं इसे ओ (एन लॉग के) उदाहरण के लिए उपयोग करना चाहता हूं एक ढेर, जो संभवतः तेज़ी से आगे बढ़ेगा, और जो काम करने वाली सेट मेमोरी को के पर भी कम कर देता है।

क्या मानक कमांड लाइन उपकरण का कुछ संयोजन है जो इसे कुशलता से कर सकता है, मुझे कुछ कोड करने के बिना? आदर्श रूप से यह सॉर्ट कमांड की पूर्ण अभिव्यक्तिपूर्ण सॉर्ट पावर का समर्थन करेगा। सॉर्ट (कम से कम उबंटू पर) में कोई मैन-पेज-डॉक्यूमेंटेड स्विच नहीं है, इसे खींचने के लिए ...

+0

क्या आपने उपरोक्त पाइप को बेंचमार्क किया है? यह कितना तेज़ है और आपको इसकी कितनी तेज़ी से आवश्यकता है? –

+1

ने बेंचमार्क नहीं किया है; लेकिन यह विभिन्न डेटासेट्स पर अन्वेषक है (यानी हर बार जब यह एक बंद हो जाता है, तो मैं इसे समाप्त करने के लिए प्रतीक्षा करने वाली कमांड लाइन पर हूं), और अजीब बात यह है कि मैं इनपुट के गीगाबाइट्स पर दस मिनट तक जा सकता हूं - विशेष रूप से जघन्य जब टीएमपी/अंत के पास बहती है। मुझे लगता है कि एक बेहतर तरीका है। मैं इनपुट को छेड़छाड़ करके, प्रत्येक को सॉर्ट करने और डेटा को डीक करने के लिए सिर/पूंछ का उपयोग करके टीएमपी/ओवरफ्लो प्राप्त कर सकता हूं, और फिर अंतिम पास में पुनः संयोजित कर सकता हूं; लेकिन यदि एक लाइनर उपलब्ध है तो यह करने के लिए एक बड़ी परेशानी है। – jdowdell

+0

क्या आपने डेटा सेट की खोज के लिए डिज़ाइन की गई भाषा का उपयोग करने पर विचार किया है, जैसे आर? –

उत्तर

1

यूनिक्स/लिनक्स सामान्यीकृत टूलसेट प्रदान करता है। बड़े डेटासेट के लिए यह I/O का भार करता है। यह वह सब कुछ करेगा जो आप चाहते हैं, लेकिन धीरे-धीरे। अगर हमें इनपुट डेटा का कोई विचार था तो इससे बहुत मदद मिलेगी।

आईएमओ, आपके पास कुछ विकल्प हैं, कोई भी आपको वास्तव में पसंद नहीं करेगा।

  1. एक बहुखण्डीय "मूलांक" पूर्व तरह करते हैं - उदाहरण के लिए awk लाइनों जिसका कुंजी एक फ़ाइल 'बी' एक और, आदि के लिए करने के लिए 'ए' के ​​साथ या यदि आप केवल 'पी शुरू के सभी लिखना है 'डी' & 'क्यू', क्या आप चाहते हैं कि बस चूस जाओ। फिर एक छोटे से सबसेट पर एक पूर्ण प्रकार करें। यह ए, बी नामक 26 फाइलें बनाता है ... जेड

    awk '{print $ 0> substr ($ 0,1,1)} bigfile; सॉर्ट करें [विकल्प यहाँ] पी डी क्यू> परिणाम

  2. $$ खर्च करें: (उदाहरण) iri.com से किसी अन्य सॉफ़्टवेयर से CoSort खरीदें। इस तरह के सभी प्रकार के अनुकूलन का उपयोग करते हैं, लेकिन वे बैश की तरह मुक्त नहीं हैं। आप एक एसएसडी भी खरीद सकते हैं जो परिमाण के कई आदेशों से डिस्क पर सॉर्टिंग की गति बढ़ाता है। 5000iops अब 75000iops पर। एसएसडी पर अपनी टीएमपी फाइलों को रखने के लिए TMPDIR वैरिएबल का उपयोग करें, केवल एसएसडी को पढ़ें और लिखें। लेकिन अपने मौजूदा यूनिक्स टूलसेट का उपयोग करें।

  3. कुछ सॉफ्टवेयर जैसे आर या स्ट्रेट, या अधिमानतः डेटाबेस का उपयोग करें; ये सभी बड़े डेटासेट के लिए हैं।

  4. अब आप जो कर रहे हैं, वही करें, लेकिन यूनिक्स सॉर्ट चलाने के दौरान यूट्यूब देखें।

आईएमओ, आप त्वरित डेटा चाहते समय बड़े डेटासेट के लिए गलत टूल का उपयोग कर रहे हैं।

#!/usr/bin/perl 

use strict; 
use warnings; 

my @lines =(); 

while (<>) { 
    push @lines, $_; 
    @lines = sort @lines; 
    if (scalar @lines > 10) { 
     pop @lines; 
    } 
} 
print @lines; 

यह केवल एक बार इनपुट डेटा पढ़ता है, लगातार शीर्ष 10 लाइनों की एक क्रमबद्ध सरणी बनाए रखने:

+0

जहां तक ​​मैं कह सकता हूं, आपके कोई भी सुझाव इस तथ्य का लाभ नहीं उठाता है कि ओपी को केवल "शीर्ष * के *" परिणाम सेट की आवश्यकता होती है; यानी, आप इस सवाल का जवाब दे रहे हैं कि "मैं 'प्रकार' के बराबर कैसे कर सकता हूं, लेकिन तेज़?", जो कि सवाल नहीं है। (दाएं?) – ruakh

+0

उसका (1) पता टीएमपी/ओवरफ्लो, और उसका (3) संभावित रूप से इस तरह का अनुकूलन करता है। मुझे CoSort (2) के बारे में पता नहीं है, लेकिन शायद यह भी इन चीजों को करता है। मैं मानता हूं कि कभी-कभी डेटा पर सही टूल खरीदने/स्थापित करने के लायक है, और मैं इसे आवश्यकतानुसार कर सकता हूं; सवाल यह है कि "जब मैं खुद को इस स्थिति में ढूंढता हूं, तो क्या एक त्वरित हैक है?" – jdowdell

0

यहाँ एक कच्चे आंशिक समाधान है।

हर बार पूरे सरणी को सॉर्ट करना अक्षम है, लेकिन मुझे लगता है कि एक गीगाबाइट इनपुट के लिए यह अभी भी sort huge-file | head से काफी तेज होगा।

मुद्रित लाइनों की संख्या को बदलने के लिए एक विकल्प जोड़ना काफी आसान होगा। सॉर्टिंग कैसे किया जाता है इसे नियंत्रित करने के लिए विकल्पों को जोड़ना थोड़ा मुश्किल होगा, हालांकि अगर CPAN में कुछ है तो मुझे आश्चर्य नहीं होगा कि इससे मदद मिलेगी।

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

आप इनपुट को मध्यम आकार के हिस्सों में विभाजित कर सकते हैं, प्रत्येक चंक की शीर्ष एन लाइनों को प्राप्त करने के लिए कुछ चालाक एल्गोरिदम लागू कर सकते हैं, एक साथ भाग को जोड़ सकते हैं, फिर परिणाम के लिए उसी एल्गोरिदम लागू कर सकते हैं। भाग के आकार के आधार पर, sort ... | head पर्याप्त चालाक हो सकता है। ऐसा करने के लिए split -l ... का उपयोग करके एक खोल स्क्रिप्ट को एक साथ फेंकना मुश्किल नहीं होना चाहिए।

(सम्मिलित करें अधिक हाथ लहराते के रूप में की जरूरत है।)

अस्वीकरण: मैं सिर्फ तुम क्या (लगभग 17 लाख लाइनों) के साथ काम कर रहे हैं की तुलना में काफी छोटे फ़ाइल पर यह कोशिश की, और मेरे विधि sort ... | head धीमी गति से था ।

2

उपरोक्त के आधार पर, और कुछ और पोकिंग, मैं कहूंगा कि मेरे प्रश्न का आधिकारिक उत्तर "कोई समाधान नहीं है।" आप विशेष उपकरण का उपयोग कर सकते हैं, या आप अपने वर्तमान प्रदर्शन के साथ प्राप्त टूल का उपयोग कर सकते हैं, या आप अपना स्वयं का टूल लिख सकते हैं।

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

  • 256 फ़ाइलें लगभग 1.6 Gigs कुल आकार के, सभी एक SSD पर बैठे, लाइनों द्वारा अलग \ n, प्रारूप की रेखाएं [^ \ t] * \ t [0-9] +
  • उबंटू 10.4, 6 कोर, 8 गीगा रैम,/एसएसडी पर टीएमपी भी।
  • $ time sort -t^v<tab> -k2,2n foo* | tail -10000
    • असली 7m26.444s
    • उपयोगकर्ता 7m19.790s
    • sys 0m17.530s
  • $ time python test.py 10000 foo*
    • असली 1m29.935s
    • उपयोगकर्ता 1m28.640s
    • sys 0m1.220s
  • विश्लेषण के लिए भिन्नता का उपयोग करते हुए, दो विधियां टाई-ब्रेकिंग पर भिन्न होती हैं, लेकिन अन्यथा सॉर्ट ऑर्डर समान होता है।

परीक्षण।पीई:

#!/usr/bin/env python 
# test.py 

from sys import argv 
import heapq 
from itertools import chain 

# parse N - the size of the heap, and confirm we can open all input files 
N = int(argv[1]) 
streams = [open(f, "r") for f in argv[2:]] 

def line_iterator_to_tuple_iterator(line_i): 
    for line in line_i: 
     s,c = line.split("\t") 
     c = int(c) 
     yield (c, s) 

# use heap to process inputs 
rez = heapq.nlargest(N, 
       line_iterator_to_tuple_iterator(chain(*streams)), 
       key=lambda x: x[0]) 

for r in rez: 
    print "%s\t%s" % (r[1], r[0]) 

for s in streams: 
    s.close() 

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

  • कोई संबंधित समस्या नहीं^_^