2015-12-24 4 views
7

मेरे पास 120 जीबी के कुल आकार के साथ कई जीजे फ़ाइलें हैं। मैं उन फ़ाइलों को एक ही निर्देशिका में अनजिप (gzip) करना चाहता हूं और मौजूदा gz फ़ाइल को हटा देना चाहता हूं। वर्तमान में हम इसे मैन्युअल रूप से कर रहे हैं और gzip -d <filename> का उपयोग करके अनजिप करने में अधिक समय लग रहा है।
क्या कोई तरीका है कि मैं एक पायथन स्क्रिप्ट या किसी अन्य तकनीक को बनाकर समानांतर में उन फ़ाइलों को अनजिप कर सकता हूं। वर्तमान में ये फ़ाइलें लिनक्स मशीन पर हैं।बहु थ्रेडिंग का उपयोग करके पाइथन में एकाधिक gz फ़ाइलों को अनजिप कैसे करें?

उत्तर

0

दीवार घड़ी के समय का एक बड़ा खंड gunzip या gzip -d के साथ फ़ाइल को डिकंप्रेस करने में बिताया I/O संचालन (डिस्क पर पढ़ने और लिखने) से होगा। यह वास्तव में डेटा को कम करने के लिए खर्च किए गए समय से भी अधिक हो सकता है। आप पृष्ठभूमि में कई gzip नौकरियां जाकर इसका लाभ उठा सकते हैं। चूंकि कुछ नौकरियां I/O पर अवरुद्ध होती हैं, इसलिए एक और नौकरी वास्तव में कतार में प्रतीक्षा किए बिना चल सकती है।

आप पृष्ठभूमि में चल रहे एकाधिक gunzip प्रक्रियाओं के द्वारा पूरे फ़ाइल सेट की डिकंप्रेसरिंग को तेज कर सकते हैं। प्रत्येक फाइल के एक विशिष्ट सेट की सेवा।

आप बाश में कुछ आसान बना सकते हैं। फ़ाइल सूची को अलग-अलग कमांड में विभाजित करें और इसे पृष्ठभूमि नौकरी के रूप में शुरू करने के लिए & का उपयोग करें। फिर प्रत्येक प्रत्येक नौकरी खत्म करने के लिए wait

मैं आपको सलाह दूंगा कि आपके पास 2 से 2 * एन नौकरियां एक साथ चल रही हैं। जहां एन आपके कंप्यूटर पर कोर या लॉजिकल प्रोसेसर की संख्या है। सही संख्या प्राप्त करने के लिए उपयुक्त प्रयोग।

आप बाश में कुछ आसान बना सकते हैं।

#!/bin/bash 

argarray=("[email protected]") 
len=${#argarray[@]} 

#declare 4 empty array sets 
set1=() 
set2=() 
set3=() 
set4=() 

# enumerate over each argument passed to the script 
# and round robin add it to one of the above arrays 

i=0 
while [ $i -lt $len ] 
do 

    if [ $i -lt $len ]; then 
     set1+=("${argarray[$i]}") 
     ((i++)) 
    fi 

    if [ $i -lt $len ]; then 
     set2+=("${argarray[$i]}") 
     ((i++)) 
    fi 

    if [ $i -lt $len ]; then 
     set3+=("${argarray[$i]}") 
     ((i++)) 
    fi 

    if [ $i -lt $len ]; then 
     set4+=("${argarray[$i]}") 
     ((i++)) 
    fi 
done 

# for each array, start a background job 
gzip -d ${set1[@]} & 
gzip -d ${set2[@]} & 
gzip -d ${set3[@]} & 
gzip -d ${set4[@]} & 

# wait for all jobs to finish  
wait 

उपरोक्त उदाहरण में, मैं काम के अनुसार 4 फ़ाइलों उठाया और दो अलग-अलग नौकरियों शुरू कर दिया। आप आसानी से स्क्रिप्ट का विस्तार कर सकते हैं ताकि अधिक नौकरियां, प्रति प्रक्रिया अधिक फाइलें और फ़ाइल नाम कमांड लाइन पैरामीटर के रूप में ले सकें।

+0

आपके उत्तर के लिए धन्यवाद, लेकिन मैं इस प्रक्रिया को स्वचालित करना चाहता हूं। मान लीजिए कि मेरे पास मेरी निर्देशिका में 50 फाइलें हैं, तो मैं चाहता हूं कि इन्हें समानांतर रूप से अनजिप किया जाए ताकि मैं समय कम कर सकूं। वर्तमान में मेरे पास मानक अनुक्रम संख्याओं के साथ फ़ाइल नाम हैं 01 से 50 इसलिए मैं एक जीजीआईपी कमांड में पहली 10 फाइलों को पास कर रहा हूं जैसे कि मेरे पास 5 प्रक्रियाएं हैं। इसलिए मैं पहले 5 नौकरियों के लिए धागा बनाना चाहता हूं जैसे बुद्धिमान मैं 10 थ्रेड शुरू कर सकता हूं। मेरा सवाल यह है कि यह अजगर में संभव है? – user3743797

+0

कुछ प्रकार के बैश स्क्रिप्टिंग के साथ, आप इसे प्राप्त कर सकते हैं। अपनी बैश स्क्रिप्ट के कमांड लाइन पैरामीटर को सरणी में कनवर्ट करें। फिर 4 अलग सरणी में विभाजित करें। प्रत्येक सरणी एक अलग 'gzip -d' कॉल बन जाती है। मैं देखूंगा कि मैं बाद में कुछ काम कर सकता हूं ... – selbie

+0

@ user3743797 - अब यह काम करता है। आप 'script.sh * .gz' का आह्वान कर सकते हैं या यह वही करेगा जो आप चाहते हैं। मैं उन फ़ाइलों के सेट से अलग निर्देशिका में स्क्रिप्ट रखने का सुझाव दूंगा जो आप चालू करना चाहते हैं। – selbie

8

आप multiprocessing Pools के साथ बहुत आसानी से कर सकते हैं:

import gzip 
import multiprocessing 
import shutil 

filenames = [ 
    'a.gz', 
    'b.gz', 
    'c.gz', 
    ... 
] 

def uncompress(path): 
    with gzip.open(path, 'rb') as src, open(path.rstrip('.gz'), 'wb') as dest: 
     shutil.copyfileobj(src, dest) 

with multiprocessing.Pool() as pool: 
    for _ in pool.imap_unordered(uncompress, filenames, chunksize=1): 
     pass 

इस कोड को कुछ प्रक्रियाओं अंडे जाएगा, और प्रत्येक प्रक्रिया एक समय में एक फ़ाइल निकालने होंगे।

यहां कुछ फ़ाइलों को औसत से बड़ा होने पर रोकने के लिए मैंने chunksize=1 चुना है।

+0

हाय एंड्रिया, आपके उत्तर के लिए धन्यवाद। तो अगर मैं सही ढंग से समझता हूं। हम एक समय में 4 फाइलें संसाधित कर रहे हैं? अगर एक फ़ाइल समाप्त हो गई है तो यह अगली फाइल (5 वां फाइल) ले जाएगी। कृपया पुष्टि करें। – user3743797

+0

@ user3743797: यह सही है –

+0

पुष्टिकरण के लिए धन्यवाद, अगर मैं निर्देशिका स्थान को पास करने के बजाय फ़ाइलों को हार्डकोड नहीं करना चाहता हूं तो यह फाइलों को उठाएगा। पूल करता है।imap_unordered विधि फ़ाइल नाम के लिए इनपुट के रूप में निर्देशिका स्थान स्वीकार करते हैं? – user3743797

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