os.walk für Admins


Zum testen habe ich mir eine kleine Spielwiese erstellt:

/tmp/spielwiese/
├── ordner_a
│   └── test_1.txt
├── ordner_b
│   ├── test_2.py
│   ├── unterordner_a
│   └── unterordner_b
│       ├── test_I.h
│       ├── test_II.c
│       ├── test_III.c
│       └── test_IV.c
└── test.txt

4 directories, 7 files

Erstellt wurde sie mit folgenden Befehlen:

mkdir -p /tmp/spielwiese/ordner_a
mkdir -p /tmp/spielwiese/ordner_b/unterordner_a
mkdir /tmp/spielwiese/ordner_b/unterordner_b
touch /tmp/spielwiese/test.txt
touch /tmp/spielwiese/ordner_a/test_1.txt
touch /tmp/spielwiese/ordner_b/test_2.py
touch /tmp/spielwiese/ordner_b/unterordner_b/test_I.h
touch /tmp/spielwiese/ordner_b/unterordner_b/test_II.c
touch /tmp/spielwiese/ordner_b/unterordner_b/test_III.c
touch /tmp/spielwiese/ordner_b/unterordner_b/test_IV.c

Eine klassische Nutzung von os.walk sähe dann ungefähr so aus:

import os
for (directory, subdirectories, files) in os.walk('/tmp/spielwiese'):
    print(directory)
    print(subdirectories)
    print(files)

Der Start wäre das Verzeichnis /tmp/spielwiese. Bei jedem Durchlauf werden dann die Variablen directory, subdirectories und files gefüllt. Das kommt kommt ungefähr einem ls gleich, den ich im entsprechenden Verzeichnis ausführe.

Ein praktisches Beispiel, das ein Array mit allen Dateien erzeugt sähe dann so aus:

filearray = []
for (directory, subdirectories, files) in os.walk('/tmp/spielwiese'):
    for f in files:
    filearray.append(os.path.join(directory, f))

Die Variable filearray beinhaltet dann folgendes:

['/tmp/spielwiese/test.txt', '/tmp/spielwiese/ordner_b/test_2.py', '/tmp/spielwiese/ordner_b/unterordner_b/test_I.h', '/tmp/spielwiese/ordner_b/unterordner_b/test_III.c', '/tmp/spielwiese/ordner_b/unterordner_b/test_II.c', '/tmp/spielwiese/ordner_b/unterordner_b/test_IV.c', '/tmp/spielwiese/ordner_a/test_1.txt']

Sehr praktisch ist hier die Funktion os.path.join. Die Hilfe besagt, dass diese Funktion ein oder mehrer Pfadkomponenten intelligent mit einader verbindet. Letztendlich baut sie mir, einen Pfad sauber zusammen, so dass ich nicht auf die / achten muss.

Wenn man nun statt dem vollen Pfad, den relative Pfad haben möchte, kann man folgendes machen:

start = '/tmp/spielwiese'
filearray = []
for (directory, subdirectories, files) in os.walk(start):
    for f in files:
        i = os.path.join(directory, f)
        filearray.append(os.path.relpath(i, start))