2009-05-30 13 views
79

यूनिक्स sort कमांड इस तरह की एक बहुत बड़ी फ़ाइल को सॉर्ट कर सकता है:यूनिक्स सॉर्ट कमांड कैसे एक बहुत बड़ी फाइल को सॉर्ट कर सकता है?

sort large_file 

सॉर्ट एल्गोरिदम कैसे कार्यान्वित किया जाता है?

यह कैसे स्मृति की अत्यधिक खपत का कारण नहीं बनता है?

+0

फिर से आदेश संपादित किया गया। UUoC। ;) – ayaz

+0

यह दिलचस्प है। मैं वास्तव में नहीं जानता कि यह कैसे काम करता है, लेकिन मुझे लगता है। यह शायद प्रत्येक कुंजी के पहले चरित्र को बाइनरी पेड़ में रखता है, और जब टक्कर होती है, तो यह कुंजी के अगले चरित्र का भी उपयोग करती है, इसलिए यह उस कुंजी से अधिक कुंजी को सहेजती नहीं है।फिर यह प्रत्येक कुंजी के साथ फ़ाइल में ऑफसेट को सहेज सकता है ताकि वह प्रत्येक पंक्ति को वापस ले और प्रिंट कर सके। – Zifre

+0

असल में, @ayaz यह अधिक दिलचस्प है यदि आप डिस्क पर फ़ाइल को सॉर्ट नहीं कर रहे हैं बल्कि एक पाइप में हैं क्योंकि यह स्पष्ट करता है कि आप इनपुट डेटा पर एकाधिक पास नहीं कर सकते हैं। – tvanfosson

उत्तर

93

Algorithmic details of UNIX Sort command का कहना है कि यूनिक्स सॉर्ट एक बाहरी आर-वे विलय सॉर्टिंग एल्गोरिदम का उपयोग करता है। लिंक अधिक जानकारी में जाता है, लेकिन संक्षेप में यह इनपुट को छोटे हिस्सों में विभाजित करता है (जो स्मृति में फिट होता है) और फिर अंत में प्रत्येक भाग को विलय करता है।

33

sort कमांड अस्थायी डिस्क फ़ाइलों में काम करने वाले डेटा स्टोर करता है (आमतौर पर /tmp में)।

+16

temp dir –

11

मैं प्रोग्राम से परिचित नहीं हूं लेकिन मुझे लगता है कि यह बाहरी सॉर्टिंग के माध्यम से किया जाता है (अधिकांश समस्या अस्थायी फ़ाइलों में होती है जबकि समस्या का अपेक्षाकृत छोटा हिस्सा एक समय में स्मृति में आयोजित होता है)। विषय की बहुत गहन चर्चा के लिए डोनाल्ड Knuth के The Art of Computer Programming, Vol. 3 Sorting and Searching, Section 5.4 देखें।

13

चेतावनी: यह स्क्रिप्ट वास्तव में बड़ी फ़ाइलों के लिए एक शेल प्रति शंक शुरू करती है, यह सैकड़ों हो सकती है।


यहां एक स्क्रिप्ट है जिसे मैंने इस उद्देश्य के लिए लिखा था। 4 प्रोसेसर मशीन पर यह 100% तक सॉर्ट प्रदर्शन में सुधार हुआ!

#! /bin/ksh 

MAX_LINES_PER_CHUNK=1000000 
ORIGINAL_FILE=$1 
SORTED_FILE=$2 
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split. 
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted 

usage() 
{ 
    echo Parallel sort 
    echo usage: psort file1 file2 
    echo Sorts text file file1 and stores the output in file2 
    echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines 
    echo and each chunk will be sorted in parallel 
} 

# test if we have two arguments on the command line 
if [ $# != 2 ] 
then 
    usage 
    exit 
fi 

#Cleanup any lefover files 
rm -f $SORTED_CHUNK_FILES > /dev/null 
rm -f $CHUNK_FILE_PREFIX* > /dev/null 
rm -f $SORTED_FILE 

#Splitting $ORIGINAL_FILE into chunks ... 
split -l $MAX_LINES_PER_CHUNK $ORIGINAL_FILE $CHUNK_FILE_PREFIX 

for file in $CHUNK_FILE_PREFIX* 
do 
    sort $file > $file.sorted & 
done 
wait 

#Merging chunks to $SORTED_FILE ... 
sort -m $SORTED_CHUNK_FILES > $SORTED_FILE 

#Cleanup any lefover files 
rm -f $SORTED_CHUNK_FILES > /dev/null 
rm -f $CHUNK_FILE_PREFIX* > /dev/null 

यह भी देखें: "Sorting large files faster with a shell script"

+27

निर्दिष्ट करने के लिए '-T' का उपयोग करें आप केवल जीएनयू सॉर्ट संस्करण के रूप में सॉर्ट - समांतर एन का उपयोग कर सकते हैं 8.11 – jhclark

+4

जीएनयू कोर्यूटिल्स 8.6 वास्तव में – bdeonovic

+1

यह मेरे लिए चाल है। मेरे पास 8.4 संस्करण है। सीधे फ़ाइल (1 9 0 मिलियन लाइनों) पर सॉर्ट का उपयोग करना कहीं नहीं जा रहा था। इस कार्यक्रम ने इसे 4 मिनट –

-4

मेमोरी एक समस्या नहीं होना चाहिए - तरह पहले से ही इस बात का ख्याल रखता है। यदि आप अपने बहु-कोर सीपीयू का इष्टतम उपयोग करना चाहते हैं तो मैंने इसे एक छोटी सी स्क्रिप्ट में कार्यान्वित किया है (कुछ लोगों के जैसा आप नेट पर पा सकते हैं, लेकिन उनमें से अधिकतर से सरल/क्लीनर;))। ध्यान से एक तरह से विकल्पों पर

#!/bin/bash 
# Usage: psort filename <chunksize> <threads> 
# In this example a the file largefile is split into chunks of 20 MB. 
# The part are sorted in 4 simultaneous threads before getting merged. 
# 
# psort largefile.txt 20m 4  
# 
# by h.p. 
split -b $2 $1 $1.part 
suffix=sorttemp.`date +%s` 
nthreads=$3 
i=0 
for fname in `ls *$1.part*` 
do 
    let i++ 
    sort $fname > $fname.$suffix & 
    mres=$(($i % $nthreads)) 
    test "$mres" -eq 0 && wait 
done 
wait 
sort -m *.$suffix 
rm $1.part* 
+4

दिलचस्प लिपि, लेकिन यह इस प्रश्न का उत्तर देने के लिए कुछ भी नहीं करता है। –

+5

विभाजन-बी बाइट्स द्वारा विभाजित होगा, इस प्रकार एक मनमानी स्थिति – ithkuil

11
#!/bin/bash 

usage() 
{ 
    echo Parallel sort 
    echo usage: psort file1 file2 
    echo Sorts text file file1 and stores the output in file2 
} 

# test if we have two arguments on the command line 
if [ $# != 2 ] 
then 
    usage 
    exit 
fi 

pv $1 | parallel --pipe --files sort -S512M | parallel -Xj1 sort -S1024M -m {} ';' rm {} > $2 
+0

पर लाइनों को छोटा कर रहा है यह उत्कृष्ट है। पता नहीं था कि एक समानांतर पैकेज था! क्रमबद्ध समय के बाद 50% अधिक क्रमबद्ध करें। धन्यवाद। – xbsd

+0

मैंने इस द्वारा उत्पन्न फ़ाइलों पर diff के लिए कॉम का उपयोग करने की कोशिश की और यह मुझे चेतावनी दे रहा है कि फ़ाइलों को क्रमबद्ध नहीं किया गया है। – ashishb

4

देखो प्रदर्शन में तेजी लाने और इसे अपने मशीन और समस्या पर प्रभाव है समझने के लिए। Ubuntu पर कुंजी पैरामीटर

  • अस्थायी फ़ाइलों का स्थान स्मृति के DIRECTORY_NAME
  • राशि आयकर उपयोग करने के लिए सभी स्मृति की -SN% (एन% का उपयोग करने के, और अधिक बेहतर लेकिन सदस्यता का कारण बनता है के ऊपर से बचने कर रहे हैं डिस्क पर गमागमन। आप इसे 'एस 80% "की तरह उपयोग कर सकते हैं के लिए 2 जीबी रैम उपलब्ध रैम का 80%, या" एस 2 जी "का उपयोग करें।)

प्रश्नकर्ता पूछते हैं," क्यों कोई उच्च स्मृति उपयोग ? " इसका उत्तर इतिहास से आता है, पुरानी यूनिक्स मशीनें छोटी थीं और डिफ़ॉल्ट मेमोरी आकार छोटा सेट होता है। सॉर्ट प्रदर्शन में काफी सुधार करने के लिए अपने वर्कलोड के लिए जितना संभव हो उतना बड़ा समायोजित करें। कार्यस्थल निर्देशिका को अपने सबसे तेज़ डिवाइस पर किसी स्थान पर सेट करें जिसमें कम से कम 1.25 * सॉर्ट किए जाने वाले फ़ाइल का आकार रखने के लिए पर्याप्त स्थान हो।

+0

यह 2.5 जीबी फ़ाइल पर 64 जीबी रैम के साथ एक बॉक्स पर -80% के साथ कोशिश कर रहा है, यह वास्तव में उस पूर्ण प्रतिशत का उपयोग कर रहा है, भले ही पूरी फ़ाइल उस से छोटी हो। ऐसा क्यों है? यहां तक ​​कि यदि यह एक इन-प्लेस सॉर्ट का उपयोग नहीं करता है जो कि –

+0

लगता है तो संभवतः सॉर्ट-एस फ़ाइल की सामग्री को पढ़ने से पहले सॉर्ट प्रक्रिया के लिए स्मृति आवंटित करता है। –

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