UNIX सॉर्ट कमांड एक बहुत बड़ी फाइल को कैसे सॉर्ट कर सकता है?


104

UNIX sortआदेश इस तरह एक बहुत बड़ी फ़ाइल को सॉर्ट कर सकता है:

sort large_file

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

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


यह दिलचस्प है। मैं वास्तव में नहीं जानता कि यह कैसे काम करता है, लेकिन मेरे पास एक अनुमान है। यह संभवतः प्रत्येक कुंजी के पहले चरित्र को एक बाइनरी ट्री में डालता है, और जब कोई टक्कर होती है, तो यह कुंजी के अगले चरित्र का भी उपयोग करता है, इसलिए यह कुंजी को ज़रूरत से ज़्यादा नहीं बचाता है। यह तब प्रत्येक कुंजी के साथ फाइल में एक ऑफसेट को सहेज सकता है ताकि यह वापस आ सके और प्रत्येक पंक्ति को क्रम में प्रिंट कर सके।
जिफरे ३०'०

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

3
एसओ पर हर कोई हर समय अनुमान लगाने के लिए इतना प्रभावित क्यों महसूस करता है?

आप इनपुट पर कई पास कर सकते हैं - आपको बस सभी इनपुट को पढ़ने की जरूरत है, इसे डिस्क पर लिखें, और फिर डिस्क फ़ाइल को सॉर्ट करें।

2
@ नील - संदर्भ से यह स्पष्ट लग रहा था कि वह फ़ाइल की सामग्री को फ़ाइल नाम (जो एक नाम के लिए अर्थहीन है) को क्रमबद्ध करने की कोशिश कर रहा था। मैं सिर्फ प्रसंग को बदले बिना प्रश्न को सुधारना चाहता था ताकि उसे एक साधारण गलती के कारण चढ़ाव के बजाय उत्तर मिलें।
tvanfosson

जवाबों:


111

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


42

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


20
-Tअस्थायी dir को निर्दिष्ट करने के लिए उपयोग करें
ग्लेन जैकमैन

12

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


यहाँ एक स्क्रिप्ट है जो मैंने इस उद्देश्य के लिए लिखी है। एक 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

इसे भी देखें: " शेल स्क्रिप्ट के साथ बड़ी फ़ाइलों को तेजी से सॉर्ट करना "


35
आप बस GNU सॉर्ट संस्करण 8.11
jhclark

5
GNU
Coreutils

1
इसने मेरे लिए चाल चली। मेरा सॉर्ट 8.4 वर्जन है। फ़ाइल पर सीधे सॉर्ट (190 मिलियन लाइन्स) का उपयोग करना जहाँ नहीं था। इस कार्यक्रम ने इसे केवल 4 मिनट के भीतर किया
सुनील बी

फिर से, इस जवाब का सवाल से कोई लेना-देना नहीं है
वाट्स इनबॉक्‍स

2
यह स्क्रिप्ट खतरनाक है। सैकड़ों तरह की प्रक्रियाओं को शुरू करने के बाद मेरी लिनक्स मशीन ने प्रतिक्रिया खो दी ...
योंगवेई वू

11

मैं कार्यक्रम से परिचित नहीं हूं, लेकिन मुझे लगता है कि यह बाहरी छँटाई के माध्यम से किया जाता है (ज्यादातर समस्या अस्थायी फ़ाइलों में होती है जबकि समस्या का अपेक्षाकृत छोटा हिस्सा एक समय में स्मृति में होता है)। डोनाल्ड नथ के कंप्यूटर प्रोग्रामिंग के कला, वॉल्यूम देखें। 3 छंटाई और खोज, विषय की बहुत गहन चर्चा के लिए खंड 5.4


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

यह उत्कृष्ट है। पता नहीं था कि वहाँ एक समानांतर पैकेज था! ऊपर के उपयोग के बाद 50% से अधिक सॉर्ट समय में सुधार। धन्यवाद।
xbsd

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

7

प्रदर्शन की गति के प्रकार पर ध्यान से देखें और समझें कि यह आपकी मशीन और समस्या पर प्रभाव डाल रहा है। Ubuntu पर प्रमुख पैरामीटर हैं

  • अस्थायी फ़ाइलों का स्थान -T directory_name
  • मेमोरी की मात्रा का उपयोग करने के लिए -SN% (उपयोग करने के लिए सभी मेमोरी का एन%, अधिक बेहतर लेकिन डिस्क पर टैप करने का कारण बनने वाली सदस्यता से बचें। आप उपलब्ध रैम का 80% उपयोग करने के लिए इसे "-S 80%" की तरह उपयोग कर सकते हैं। या "-S 2G" 2 जीबी रैम के लिए।

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


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

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

-3

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

#!/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
विभाजन-बी बाइट्स से विभाजित होगा, इस प्रकार लाइनों को एक मनमाना स्थिति में
काट देगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.