पायथन के साथ निर्देशिकाओं के माध्यम से Iterating


157

मुझे दी गई निर्देशिका की उपनिर्देशिकाओं के माध्यम से पुनरावृति करने और फ़ाइलों की खोज करने की आवश्यकता है। अगर मुझे कोई फ़ाइल मिलती है तो मुझे उसे खोलना होगा और सामग्री को बदलना होगा और उसे अपनी लाइनों से बदलना होगा।

मैंने यह कोशिश की:

import os

rootdir ='C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        f=open(file,'r')
        lines=f.readlines()
        f.close()
        f=open(file,'w')
        for line in lines:
            newline = "No you are not"
            f.write(newline)
        f.close()

लेकिन मुझे एक त्रुटि मिल रही है। मैं क्या गलत कर रहा हूं?


12
"एक त्रुटि" - विशेष रूप से कोई त्रुटि?
डैनियल रोजमैन

1
आप फ़ाइलों / निर्देशिकाओं के साथ क्या करने की उम्मीद के बारे में थोड़ा बता सकते हैं एक बार जब आप उन के माध्यम से चलने का इरादा के रूप में काम कर रहे हो? कृपया त्रुटि विवरण भी दें।
क्रिसपॉसर

1
त्रुटि संदेश जो im हो रहा है वह है कि फ़ाइल cool.txt नहीं मिली है। मेरे परीक्षण फ़ोल्डर में मेरे पास एक अन्य फ़ोल्डर है जिसे src कहा जाता है और src फ़ोल्डर में मेरे पास एक अन्य फ़ोल्डर है जिसे मुख्य कहा जाता है, इस फ़ोल्डर में मेरे पास cool.txt है
भेड़िया

4
क्या आप प्रश्न में त्रुटि लिख सकते हैं? कष्टप्रद और अनावश्यक से परे इसे खोजने के लिए टिप्पणियों के माध्यम से पढ़ना होगा।
चार्ली पार्कर

1
एक साल से अधिक समय के बाद मुझे विश्वास नहीं हो रहा है कि मैं पोस्ट किए जाने की त्रुटि के लिए अनुरोध कर रहा हूं? @ गोल्फ
चार्ली पार्कर

जवाबों:


300

निर्देशिकाओं के माध्यम से वास्तविक चलना काम करता है जैसा कि आपने इसे कोडित किया है। यदि आप आंतरिक लूप की सामग्री को एक साधारण printकथन से प्रतिस्थापित करते हैं, तो आप देख सकते हैं कि प्रत्येक फ़ाइल मिली है:

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print os.path.join(subdir, file)

यदि आपको अभी भी उपर्युक्त रन करते समय त्रुटियाँ मिलती हैं, तो कृपया त्रुटि संदेश प्रदान करें।


पायथन 3 के लिए अपडेट किया गया

import os
rootdir = 'C:/Users/sid/Desktop/test'

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        print(os.path.join(subdir, file))

1
C: / Users / sid / Desktop / test \ src \ app / cool.txt C: / Users / sid / Desktop / test / src \ app / woohoo.txt हां मेरे कोड के खुले स्टेटमेंट में, मुझे लगता है कि मुझे फ़ाइल को पूर्ण पथ दें। आयात os रूटिर = 'C: / उपयोगकर्ता / शुक्राणु / डेस्कटॉप / परीक्षण / src / app /' सबडिडर के लिए, dirs, फाइलें os.walk (rootdir) में: फाइलों में फाइल के लिए: f = खुला (सबडिर + '/' + फाइल , "r ') लाइनें = f.readlines () f.close () f = open (सबडिर +' / '+ फ़ाइल,' w ') लाइनों में लाइन के लिए: newline =" hey i know "f.write (newline) f.close () धन्यवाद आदमी। इसका हल
भेड़िया

3
नमस्ते! कृपया ध्यान रखें कि अजगर 3 में "प्रिंट" को कोष्ठक की आवश्यकता होती है, अन्यथा एक सिंटैक्स त्रुटि होती है। उम्मीद है की यह मदद करेगा!
टॉमसो डि नोटो

14

उपनिर्देशिकाओं में सभी फाइलों को वापस करने का एक अन्य तरीका है , पायथन 3.4 में पेश किए गए pathlibमॉड्यूल का उपयोग करना , जो फाइलसिस्टम पथों को संभालने के लिए एक वस्तु उन्मुख दृष्टिकोण प्रदान करता है (पाइलिब पर पाइलिब 2 मॉड्यूल के माध्यम से पाइथन 2.7 पर उपलब्ध है ):

from pathlib import Path

rootdir = Path('C:/Users/sid/Desktop/test')
# Return a list of regular files only, not directories
file_list = [f for f in rootdir.glob('**/*') if f.is_file()]

# For absolute paths instead of relative the current dir
file_list = [f for f in rootdir.resolve().glob('**/*') if f.is_file()]

पायथन 3.5 के बाद से, globमॉड्यूल पुनरावर्ती फ़ाइल खोजने का भी समर्थन करता है:

import os
from glob import iglob

rootdir_glob = 'C:/Users/sid/Desktop/test/**/*' # Note the added asterisks
# This will return absolute paths
file_list = [f for f in iglob('**/*', recursive=True) if os.path.isfile(f)]

file_listऊपर से किसी उपाय से एक नेस्टेड पाश की आवश्यकता के बिना अधिक दोहराया जा सकता है:

for f in file_list:
    print(f) # Replace with desired operations

1
पायथन 3.6 के लिए यहां बेहतर क्या है?
फीनिक्सडेव

@PhoenixDev मैंने सामान्य रूप से दूसरे पर अनुशंसित एक दृष्टिकोण के बारे में नहीं सुना है। मैं pathlibखुद का उपयोग करना पसंद करता हूं, ज्यादातर इसलिए क्योंकि मुझे ऑब्जेक्ट ओरिएंटेड तरीके-सिंटैक्स पसंद हैं। अन्य अंतर हैं, जैसे पथ लाइब्रेरी स्ट्रिंग्स के बजाय विशिष्ट पथ कक्षाएं देता है, और उपलब्ध फ़ंक्शन पुस्तकालयों (जैसे os.path.expanduser('~')बनाम Path.home()) के बीच भिन्न होते हैं । प्रलेखन के माध्यम से ब्राउज़ करें और देखें कि आपको कौन सा दृष्टिकोण पसंद है।
जोएलोस्टब्लोम

**ग्लोब पैटर्न में जोड़ने के बजाय , आप उपयोग कर सकते हैं rglob
जॉर्जी

12

के रूप में 2020 , glob.iglob(path/**, recursive=True)लगता है सबसे pythonic समाधान, अर्थात्:

import glob, os

for filename in glob.iglob('/pardadox-music/**', recursive=True):
    if os.path.isfile(filename): # filter dirs
        print(filename)

आउटपुट:

/pardadox-music/modules/her1.mod
/pardadox-music/modules/her2.mod
...

नोट:
1 - glob.iglob

glob.iglob(pathname, recursive=False)

एक पुनरावृत्तिकर्ता लौटाएं जो समान मूल्यों को प्राप्त करता है जैसे glob()कि वास्तव में उन सभी को एक साथ संग्रहीत करने के बिना।

2 - यदि पुनरावर्ती है True, तो पैटर्न '**'किसी भी फाइल और शून्य या अधिक directoriesऔर से मेल खाएगा subdirectories

3 - यदि निर्देशिका में .वे फाइलें होती हैं जो  डिफ़ॉल्ट रूप से मेल नहीं खाएंगी। उदाहरण के लिए, युक्त निर्देशिका पर विचार करें  card.gif और .card.gif:

>>> import glob
>>> glob.glob('*.gif') ['card.gif'] 
>>> glob.glob('.c*')['.card.gif']

4 - तुम भी उपयोग कर सकते हैं rglob(pattern)बुला के रूप में है, जो एक ही है  glob() साथ**/ दिया रिश्तेदार पैटर्न के सामने गयी।


1
यह pythonic समाधान छिपा फ़ाइलों की सूची नहीं है (उर्फ dotfiles), जबकि स्वीकृत करता।
आश्रममुन

@ashrasmun आपने जो उल्लेख किया है वह docs.python.org/3/library/glob.html
CONvid19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.