2010-06-20 20 views
9

मेरे पास 100,000 से अधिक फाइलों वाला एक फ़ोल्डर है, सभी एक ही स्टब के साथ गिने गए हैं, लेकिन बिना शून्य शून्य के, और संख्याएं हमेशा संगत नहीं होती हैं (आमतौर पर वे हैं, लेकिन अंतराल हैं) उदाहरण:बैच के साथ 100K फाइलों का नाम बदलना

file-21.png, 
file-22.png, 
file-640.png, 
file-641.png, 
file-642.png, 
file-645.png, 
file-2130.png, 
file-2131.png, 
file-3012.png, 

आदि

मैं करने के लिए बैच प्रक्रिया इस गद्देदार, सन्निहित फ़ाइलें बनाने के लिए करना चाहते हैं। उदाहरण के लिए:

file-000000.png, 
file-000001.png, 
file-000002.png, 
file-000003.png, 

जब मैं for filename in os.listdir('.'): के साथ फ़ोल्डर पार्स फ़ाइलें मैं उन्हें करने के लिए करना चाहते हैं क्रम में नहीं आते हैं। जाहिर है वे आने

file-1, 
file-1x, 
file-1xx, 
file-1xxx, 

आदि तो

file-2, 
file-2x, 
file-2xx, 

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

+0

आप मापदंडों के किसी भी संख्या के साथ एक linux "ls" कमांड चला सकते में परिभाषित किया गया है। – bwawok

+1

हाँ, अगर मैं ऐसा कर रहा था, तो मैं बस 'sort -n' का उपयोग करूंगा। –

+0

उत्तर के साथ अपने प्रश्न को संपादित करने के बजाय, अपने समाधान को नीचे अपने उत्तर के रूप में पोस्ट करना बेहतर है और इसे स्वीकार किए जाने के रूप में चिह्नित करें। –

उत्तर

4

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

import os 
files = os.listdir('.') 
natsort(files) 
index = 0 
for filename in files: 
    os.rename(filename, str(index).zfill(7)+'.png') 
    index += 1 

जहां natsort उन्हें सॉर्ट आप कैसे चाहते हैं ... और फिर फ़ाइलों को पाने के लिए इस सूची का उपयोग करने के लिए http://code.activestate.com/recipes/285264-natural-string-sorting/

0

1) फ़ाइल नाम में संख्या लें। 2) इसे शून्य के साथ बाएं-पैड 3) नाम सहेजें।

+0

यह संख्याओं में अंतर को अनदेखा करता है। –

1

आप इसे दो चरणों की प्रक्रिया में क्यों नहीं करते हैं। सभी फ़ाइलों को पार्स करें और गद्देदार संख्याओं के साथ नाम बदलें और फिर एक और स्क्रिप्ट चलाएं जो उन फ़ाइलों को लेता है, जिन्हें अब सही तरीके से क्रमबद्ध किया गया है, और उन्हें नाम बदलता है ताकि वे संगत हों?

+0

नामकरण ऑपरेशन, एक सिस्टम कॉल, बाधा होगी: उनमें से कई में से दो बार करना दो गुना अधिक होगा। इसे करने के तेज़ तरीके के लिए मेरा उत्तर देखें (प्रति फ़ाइल एक ही नाम के साथ)। –

+1

आप उन्हें स्मृति में बदल देंगे, आप उन्हें वापस डिस्क पर नहीं लिखेंगे। तो केवल एक ही लिखें। –

4

तीन चरण हैं। पहले सभी फाइलनाम प्राप्त हो रहा है। दूसरा फ़ाइल नाम बदल रहा है। तीसरा उनका नाम बदल रहा है।

यदि सभी फ़ाइलें एक ही फ़ोल्डर में हैं, तो ग्लोब को काम करना चाहिए।

import glob 
filenames = glob.glob("/path/to/folder/*.txt") 

अगला, आप फ़ाइल का नाम बदलना चाहते हैं। ऐसा करने के लिए आप पैडिंग के साथ प्रिंट कर सकते हैं।

>>> filename = "file-338.txt" 
>>> import os 
>>> fnpart = os.path.splitext(filename)[0] 
>>> fnpart 
'file-338' 
>>> _, num = fnpart.split("-") 
>>> num.rjust(5, "0") 
'00338' 
>>> newname = "file-%s.txt" % num.rjust(5, "0") 
>>> newname 
'file-00338.txt' 

अब, आपको उन सभी का नाम बदलने की आवश्यकता है। os.rename बस यही करता है।

os.rename(filename, newname) 

यह एक साथ रखा करने के लिए:

for filename in glob.glob("/path/to/folder/*.txt"): # loop through each file 
    newname = make_new_filename(filename) # create a function that does step 2, above 
    os.rename(filename, newname) 
+0

यह मूल फ़ाइल नामों में छोड़ी गई संख्याओं के साथ समस्या को अनदेखा करता है - इसे आसानी से ठीक करने के तरीके के बारे में मेरा उत्तर देखें! –

8
import re 
thenum = re.compile('^file-(\d+)\.png$') 

def bynumber(fn): 
    mo = thenum.match(fn) 
    if mo: return int(mo.group(1)) 

allnames = os.listdir('.') 
allnames.sort(key=bynumber) 

अब आप चाहते हैं उन्हें क्रम में फ़ाइलें और पाश

for i, fn in enumerate(allnames): 
    ... 

प्रगतिशील संख्या i (का उपयोग कर सकते हैं, जो 0, 1, 2, ... होगा) जैसा कि आप गंतव्य नाम में चाहते हैं गद्दीदार।

+0

हो सकता है कि त्वरित सॉर्ट फ़ंक्शन डिफम्बर ​​(एफएन) हो: वापसी int (फ़िल्टर (str.isdigit, fn)) – twneale

+0

हाँ, अगर आपको यकीन है कि कहीं भी "भटक" अंक नहीं हैं तो यह तेज़ है (मेरा आरई-आधारित समाधान भी चेक करता है , और चेक का शुद्ध ओवरहेड यदि कोई "जानता है" यह हमेशा हर बार सफल होता है ;-)। –

0
def renamer(): 
    for iname in os.listdir('.'): 
     first, second = iname.replace(" ", "").split("-") 
     number, ext = second.split('.') 
     first, number, ext = first.strip(), number.strip(), ext.strip() 
     number = '0'*(6-len(number)) + number # pad the number to be 7 digits long 
     oname = first + "-" + number + '.' + ext 
     os.rename(iname, oname) 
    print "Done" 

आशा इस

+0

धन्यवाद, मैं जो समझ सकता हूं उससे, यह केवल मौजूदा संख्याओं को पैड करेगा और अनुक्रम को अंतराल के बिना संगत नहीं करेगा? – memo

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