Python ile dizinler üzerinden yineleme


158

Belirli bir dizinin alt dizinleri üzerinden yineleme ve dosyaları aramak gerekiyor. Bir dosya alırsam, dosyayı açıp içeriği değiştirip kendi satırlarımla değiştirmem gerekir.

Bunu denedim:

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()

ama bir hata alıyorum. Neyi yanlış yapıyorum?


13
"Bir hata" - özellikle herhangi bir hata?
Daniel Roseman

1
Lütfen dosyaları istediğiniz gibi yürüdükten sonra dosyalar / dizinlerle ne yapmayı umduğunuzu biraz açıklayabilir misiniz? Lütfen hata ayrıntılarını da sağlayın.
ChrisProsser

1
Im alma hata iletisi cool.txt dosyası bulunamadı olmasıdır. Benim test klasöründe src adlı başka bir klasör var ve src klasöründe main adlı başka bir klasör var, bu klasörde cool.txt var
Wolf

4
sadece soruya hata yazabilir misiniz? Bu sinir bozucu ötesinde ve bulmak için yorumları okumak zorunda gereksiz.
Charlie Parker

1
bir yıldan fazla bir süre sonra geri gönderilmesi için hata talep inanamıyorum? @Wolf
Charlie Parker

Yanıtlar:


302

Dizinler üzerinden gerçek yürüyüş, kodladığınız gibi çalışır. İç döngünün içeriğini basit bir printifadeyle değiştirirseniz, her dosyanın bulunduğunu görebilirsiniz:

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)

Yukarıdakileri çalıştırırken hala hata alıyorsanız, lütfen hata mesajını verin.


Python3 için güncellendi

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: / Kullanıcılar / sid / Masaüstü / test \ src \ app / cool.txt C: / Kullanıcılar / sid / Masaüstü / test \ src \ app / woohoo.txt Kodumun açık ifadesinde Ya, sanırım dosyaya mutlak yol verin. import os rootdir = 'C: / Kullanıcılar / spemmara / Masaüstü / test / src / app /' alt dizin, dirs, os.walk (rootdir) içindeki dosyalar için: dosyalardaki dosya için: f = open (subdir + '/' + file , 'r') lines = f.readlines () f.close () f = open (alt dizin + '/' + dosya, 'w') satırlardaki satır için: newline = "hey i know" f.write (newline) f.close () Teşekkürler adamım. Çözüldü
Wolf

3
Selam! Lütfen, python 3'teki "yazdır" ın parantez gerektirdiğini, aksi halde bir sözdizimi hatası döndürdüğünü unutmayın. Bu yardımcı olur umarım!
Tommaso Di Noto

14

Alt dizinleri tüm dosyaları dönen bir başka yolu ise modül (yoluyla Python 2.7 Pathlib da mevcuttur dosya sistemi yolları işleme için bir nesne yönelimli yaklaşım sağlar Python 3.4, tanıtılan PyPi ile pathlib2 modülü ):pathlib

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()]

Python 3.5'ten bu yana, globmodül özyinelemeli dosya bulmayı da destekler:

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_listYukarıdaki yöntemlerden herhangi biriyle gelen iç içe geçmiş bir döngü gerek kalmadan iterated edilebilir:

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

1
Burada Python 3.6 için tercih edilen nedir?
PhoenixDev

@PhoenixDev Genel olarak bir yaklaşımın diğerine önerildiğini duymadım. pathlibKendimi kullanmayı tercih ederim , çünkü çoğunlukla nesne yönelimli yöntemleri-sözdizimini seviyorum. Yol kitaplığı, dizeler yerine belirli yol sınıfları döndürür ve kullanılabilir işlevler kitaplıklar arasında farklılık gösterir (ör. os.path.expanduser('~')Vs Path.home()) gibi başka farklılıklar da vardır . Belgelere göz atın ve hangi yaklaşımı tercih ettiğinizi görün.
joelostblom

**Glob desenine eklemek yerine kullanabilirsiniz rglob.
Georgy

12

İtibariyle 2020 , glob.iglob(path/**, recursive=True)en çok görünüyor pythonic çözüm, yani:

import glob, os

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

Çıktı:

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

Notlar:
1 - glob.iglob

glob.iglob(pathname, recursive=False)

glob()Hepsini aynı anda saklamadan aynı değerleri veren bir yineleyici döndürün .

2 - Özyinelemeli ise True, desen '**'herhangi bir dosyayla ve sıfır veya daha fazla directoriesve ile eşleşir subdirectories.

3 - Dizin ile başlayan dosyalar varsa,  .bunlar varsayılan olarak eşleştirilmez. Örneğin, bir dizin içeren düşünün  card.gif ve .card.gif:

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

4 - Ayrıca , verilen göreli örüntünün önüne eklenen  ile rglob(pattern)çağırma glob()ile aynı olanı  kullanabilirsiniz **/.


1
Bu pythonic çözümü, kabul edilen dosyada gizli dosyaları (aka dotfiles olarak) listelemez.
ashrasmun

@ashrasmun Söyledikleriniz iyi açıklanmıştır docs.python.org/3/library/glob.html
CONvid19
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.