2013-11-27 7 views
6

द्वारा क्रमबद्ध करें मैं एक प्रोग्राम लिखने की कोशिश कर रहा हूं जो कमांड लाइन तर्क लेता है, तर्क द्वारा प्रदान की गई निर्देशिका पेड़ के माध्यम से स्कैन करता है और निर्देशिका में प्रत्येक फ़ाइल की एक सूची बनाते हैं, और फिर सॉर्टिंग फाइलों की लंबाई से।निर्देशिका तर्क से फ़ाइलें प्राप्त करें, आकार

मैं एक स्क्रिप्ट-पुरुष के ज्यादा नहीं कर रहा हूँ - लेकिन इस मैं क्या मिल गया है और यह काम नहीं कर रहा:

import sys 
import os 
from os.path import getsize 

file_list = [] 

#Get dirpath 
dirpath = os.path.abspath(sys.argv[0]) 
if os.path.isdir(dirpath): 
    #Get all entries in the directory 
    for root, dirs, files in os.walk(dirpath): 
     for name in files: 
      file_list.append(name) 
     file_list = sorted(file_list, key=getsize) 
     for item in file_list: 
      sys.stdout.write(str(file) + '\n') 

else: 
    print "not found" 

किसी को भी सही दिशा में मुझे बात कर सकते हैं?

+0

मैं ओ समारोह [ 'के लिए सहायता पढ़ने के लिए सुझाव देते हैं s.walk'] (http://docs.python.org/2/library/os.html#os.walk)। यह निर्देशिका पेड़ से निपटने के लिए सही विकल्प प्रतीत होता है। यदि आप इस फ़ंक्शन के लिए उदाहरण देखते हैं, तो आप देखेंगे, आप एक अच्छे तरीके से हैं ... – koffein

+0

मुझे लगता है कि आपकी पिछली पंक्ति से पहले आवश्यक नहीं है। असल में यह लाइन एक त्रुटि उत्पन्न कर रही है ... – koffein

+0

@koffein मैंने अपना कोड अपडेट किया है, लेकिन यह अभी भी मुझे एक त्रुटि दे रहा है। –

उत्तर

6

उम्मीद है कि इस (मैं अजगर 2.7 का उपयोग कर रहा) समारोह तुम बाहर में मदद मिलेगी:

import os  

def get_files_by_file_size(dirname, reverse=False): 
    """ Return list of file paths in directory sorted by file size """ 

    # Get list of files 
    filepaths = [] 
    for basename in os.listdir(dirname): 
     filename = os.path.join(dirname, basename) 
     if os.path.isfile(filename): 
      filepaths.append(filename) 

    # Re-populate list with filename, size tuples 
    for i in xrange(len(filepaths)): 
     filepaths[i] = (filepaths[i], os.path.getsize(filepaths[i])) 

    # Sort list by file size 
    # If reverse=True sort from largest to smallest 
    # If reverse=False sort from smallest to largest 
    filepaths.sort(key=lambda filename: filename[1], reverse=reverse) 

    # Re-populate list with just filenames 
    for i in xrange(len(filepaths)): 
     filepaths[i] = filepaths[i][0] 

    return filepaths 
+1

के साथ' फ़ाइल 'नामों में शामिल होना है, मैंने इसे कई बार पढ़ा है और मुझे लगता है कि यह काम करता है, लेकिन मैंने यह भी देखा कि आपने सभी छोटी चीजें नहीं खोजी हैं, जो आपके पायथन कोड को और अधिक सुंदर बनाती हैं और पठनीय। मुझे उम्मीद है कि आप कुछ सलाह की सराहना करते हैं: जब भी आपको लगता है कि आपको 'i i रेंज (लेन (some_list)) लिखने की आवश्यकता है, तो '' enumerate'] (http://docs.python.org/2/library/functions इसके बजाय .html # enumerate)। यदि आप किसी सूची को फिर से पॉप्युलेट करना चाहते हैं, तो अपनी "सरणी-सोच सोचने" को छोड़ दें, इसके बजाय कुछ ऐसा करने का प्रयास करें: 'lst = [do_something (प्रविष्टि) lst में प्रविष्टि के लिए] ' – koffein

+2

लेकिन यदि आप कोई उत्पन्न करते हैं सूची, आप जेनरेटर्स का उपयोग करने के बारे में सोचने के बिना किसी भी आगे के उपयोग के बिना दोबारा तैयार करना चाहते हैं। तो आपको बार-बार एक सूची में फिर से शुरू करने की ज़रूरत नहीं है ...स्मृति बचाता है, समय ... यदि आप इसे पढ़ने से थक गए हैं, तो इस वीडियो को देखें ... पाइथन में प्रोग्रामिंग के वर्षों के बाद मैंने अपने मुंह से खुले खुले हुए देखा! [सुंदर, इडियेटोमिक पायथन में ट्रांसफॉर्मिंग कोड] (https://www.youtube.com/watch?v=OSGv2VnC0go) – koffein

+0

'dirname'' os.path' में किसी फ़ंक्शन के लिए आरक्षित नाम है, आपको इसका उपयोग नहीं करना चाहिए आपकी लिपि में एक चर नाम के रूप में। समारोह महान बीटीडब्ल्यू काम करता है! – Gabriel

0

आप कमांड निकाल रहे हैं और argv[0] के साथ पहला तर्क नहीं है; उस के लिए argv[1] का उपयोग करें:

dirpath = sys.argv[1] # argv[0] contains the command itself. 

प्रदर्शन के कारणों के लिए मैं सुझाव है कि आप फ़ाइल आकार के बजाय prefetch छंटाई के दौरान कई बार एक ही फाइल के आकार के बारे ओएस पूछ (के रूप में Koffein ने सुझाव दिया की, os.walk के लिए रास्ता है जाना):

files_list = [] 
for path, dirs, files in os.walk(dirpath)): 
    files_list.extend([(os.path.join(path, file), getsize(os.path.join(path, file))) for file in files]) 

मान लिया जाये कि आप अवर्गीकृत सूची की जरूरत नहीं है, हम में जगह प्रकार का उपयोग करेगा() विधि:

files_list.sort(key=operator.itemgetter(1)) 
+0

'फाइल' सूची सिर्फ फाइल-नामों की एक सूची है, है ना? मुझे लगता है कि आपको 'पथ' – koffein

5

इस जनरेटर का उपयोग एक दृष्टिकोण है। फ़ाइलों की बड़ी संख्या के लिए तेजी से होना चाहिए ...

यह दोनों उदाहरण की शुरुआत है:

sorted_files = sorted(all_files, key = os.path.getsize) 
:

import os, operator, sys 
dirpath = os.path.abspath(sys.argv[0]) 
# make a generator for all file paths within dirpath 
all_files = (os.path.join(basedir, filename) for basedir, dirs, files in os.walk(dirpath) for filename in files ) 

तुम सिर्फ आकार के बिना फ़ाइलों की एक सूची चाहते हैं, तो आप इस का उपयोग कर सकते

लेकिन अगर आप किसी सूची में फ़ाइलों और रास्तों चाहते हैं, तो आप इस का उपयोग कर सकते हैं:

# make a generator for tuples of file path and size: ('/Path/to/the.file', 1024) 
files_and_sizes = ((path, os.path.getsize(path)) for path in all_files) 
sorted_files_with_size = sorted(files_and_sizes, key = operator.itemgetter(1)) 
+0

पहले सबसे बड़ी फ़ाइलों को देखने के लिए 'sorted_files_with_size.reverse()' का उपयोग करें। यह बहुत तेज़ है और यह जानने के लिए उपयोगी है कि कौन सी फाइलें स्थान ले रही हैं। –

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