Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis

Lesezeit: 6 Minuten

Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
mhost

Ich versuche, mit Python eine Liste von Dateien in einem Verzeichnis zu erhalten, aber ich möchte keine Liste ALLER Dateien.

Was ich im Wesentlichen möchte, ist die Fähigkeit, etwas wie das Folgende zu tun, aber Python zu verwenden und ls nicht auszuführen.

ls 145592*.jpg

Wenn es dafür keine eingebaute Methode gibt, denke ich derzeit darüber nach, eine for-Schleife zu schreiben, um die Ergebnisse von an zu durchlaufen os.listdir() und um alle übereinstimmenden Dateien an eine neue Liste anzuhängen.

In diesem Verzeichnis befinden sich jedoch viele Dateien, und daher hoffe ich, dass es eine effizientere Methode (oder eine integrierte Methode) gibt.

  • [This link might help you 🙂 Get a filtered list of files in a directory ](codereview.stackexchange.com/a/33642)

    – sha111

    17. Januar 2019 um 10:09 Uhr

  • Beachten Sie, dass Sie besonders auf die Sortierreihenfolge achten sollten, wenn dies für Ihre Anwendung wichtig ist.

    – lumbrisch

    27. November 2019 um 20:22 Uhr

Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
Ignacio Vazquez-Abrams

import glob

jpgFilenamesList = glob.glob('145592*.jpg')

Sehen glob in der Python-Dokumentation

  • Oh, ich habe gerade bemerkt, dass die Python-Dokumentation sagt, dass glob() “durch die gemeinsame Verwendung der Funktionen os.listdir() und fnmatch.fnmatch() und nicht durch den tatsächlichen Aufruf einer Subshell erfolgt”. Mit anderen Worten, glob() hat nicht die Effizienzverbesserungen, die man erwarten könnte.

    – Ben Hoyt

    11. Februar 2010 um 4:28 Uhr

  • Es gibt einen Hauptunterschied: glob.glob('145592*.jpg') druckt den gesamten absoluten Pfad der Dateien während ls 145592*.jpg druckt nur die Liste der Dateien.

    – Ebe Isaac

    2. Dezember 2016 um 18:12 Uhr

  • @Ben Warum sollte das Aufrufen einer Unterschale (Unterprozess) Effizienzverbesserungen bringen?

    – Paul Neves

    18. Januar 2017 um 8:08 Uhr

  • @PauloNeves: Stimmt, mein obiger Kommentar ergibt für mich auch 7 Jahre später keinen Sinn. 🙂 Ich vermute, ich bezog mich auf die Tatsache, dass glob() verwendet einfach listdir+fnmatch anstelle spezieller Betriebssystemaufrufe, um die Wildcard-Filterung durchzuführen. Zum Beispiel unter Windows die FindFirstFile Mit der API können Sie Platzhalter angeben, damit das Betriebssystem die Filterung direkt und vermutlich effizienter durchführt (ich glaube nicht, dass es unter Linux ein Äquivalent gibt).

    – Ben Hoyt

    18. Januar 2017 um 16:28 Uhr

  • Verwendung nicht vergessen import glob

    – Himmel

    19. März 2020 um 23:29 Uhr

glob.glob() ist definitiv der Weg, es zu tun (gemäß Ignacio). Wenn Sie jedoch einen komplizierteren Abgleich benötigen, können Sie dies mit einem Listenverständnis und tun re.match()ungefähr so:

files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)]

Flexibler, aber wie Sie bemerken, weniger effizient.

  • Dies scheint definitiv stärker zu sein. Zum Beispiel etwas tun müssen wie [0-9]+

    – Dämongolem

    10. Januar 2013 um 17:03 Uhr

  • Ja, definitiv leistungsfähiger – aber fnmatch unterstützt [0123456789] Sequenzen (siehe Dokumente), und es hat auch die fnmatch.filter() Funktion, die diese Schleife etwas effizienter macht.

    – Ben Hoyt

    10. Januar 2013 um 22:42 Uhr

1647534969 445 Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
ramsey0

Halte es einfach:

import os
relevant_path = "[path to folder]"
included_extensions = ['jpg','jpeg', 'bmp', 'png', 'gif']
file_names = [fn for fn in os.listdir(relevant_path)
              if any(fn.endswith(ext) for ext in included_extensions)]

Ich bevorzuge diese Form des Listenverständnisses, weil sie sich auf Englisch gut lesen lässt.

Ich lese die vierte Zeile wie folgt: Geben Sie mir für jeden fn in os.listdir für meinen Pfad nur diejenigen, die mit einer meiner enthaltenen Erweiterungen übereinstimmen.

Für Python-Anfänger kann es schwierig sein, sich wirklich daran zu gewöhnen, Listenverständnisse zum Filtern zu verwenden, und es kann bei sehr großen Datensätzen zu einem gewissen Speicheraufwand kommen, aber zum Auflisten eines Verzeichnisses und anderer einfacher Aufgaben zum Filtern von Zeichenfolgen führen Listenverständnisse zu mehr Sauberkeit dokumentierbarer Code.

Das einzige an diesem Design ist, dass es Sie nicht davor schützt, einen String anstelle einer Liste zu übergeben. Wenn Sie beispielsweise versehentlich eine Zeichenfolge in eine Liste konvertieren und am Ende alle Zeichen einer Zeichenfolge überprüfen, könnten Sie am Ende eine Menge falsch positiver Ergebnisse erhalten.

Aber es ist besser, ein Problem zu haben, das einfach zu beheben ist, als eine Lösung, die schwer zu verstehen ist.

  • Nicht, dass es dafür nötig wäre any() hier, weil str.endswith() nimmt ein Reihenfolge von Endungen. if fn.endswith(included_extentensions) ist mehr als genug.

    – Martijn Pieters

    8. Oktober 2015 um 7:10 Uhr

  • Abgesehen von der Ineffizienz des Nichtgebrauchs str.endswith(seq) dass Martijn darauf hingewiesen hat, dass dies nicht korrekt ist, da eine Datei mit enden muss .ext damit es diese Erweiterung hat. Dieser Code findet (zum Beispiel) auch eine Datei mit dem Namen “myjpg” oder ein Verzeichnis mit dem Namen “png”. Um das Problem zu beheben, setzen Sie einfach jeder Erweiterung ein Präfix voran included_extensions mit einer ..

    – Ben Hoyt

    3. November 2016 um 19:29 Uhr

  • Ich bin immer etwas vorsichtig mit Code in Antworten, der offensichtlich nicht ausgeführt wurde oder nicht ausgeführt werden kann. Die Variable included_extensions vs included_extentsions? Schade, denn ansonsten ist dies meine bevorzugte Antwort.

    – Vorzeichen

    19. März 2018 um 21:35 Uhr

1647534969 524 Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
Risadinha

Andere Option:

>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']

https://docs.python.org/3/library/fnmatch.html

Filtern mit glob Modul:

Globus importieren

import glob

Wildcards:

files=glob.glob("data/*")
print(files)

Out:

['data/ks_10000_0', 'data/ks_1000_0', 'data/ks_100_0', 'data/ks_100_1',
'data/ks_100_2', 'data/ks_106_0', 'data/ks_19_0', 'data/ks_200_0', 'data/ks_200_1', 
'data/ks_300_0', 'data/ks_30_0', 'data/ks_400_0', 'data/ks_40_0', 'data/ks_45_0', 
'data/ks_4_0', 'data/ks_500_0', 'data/ks_50_0', 'data/ks_50_1', 'data/ks_60_0', 
'data/ks_82_0', 'data/ks_lecture_dp_1', 'data/ks_lecture_dp_2']

Fiter-Erweiterung .txt:

files = glob.glob("/home/ach/*/*.txt")

Ein einzelner Charakter

glob.glob("/home/ach/file?.txt")

Nummernkreise

glob.glob("/home/ach/*[0-9]*")

Alphabet-Bereiche

glob.glob("/home/ach/[a-c]*")

1647534969 870 Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
S0UndS0

Vorläufiger Code

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path="."

Lösung 1 – Verwenden Sie “glob”

# lookup in current dir
glob.glob(pattern)

In [2]: glob.glob(pattern)
Out[2]: ['wsgi.py', 'manage.py', 'tasks.py']

Lösung 2 – Verwenden Sie “os” + “fnmatch”

Variante 2.1 – Suche im aktuellen Verzeichnis

# lookup in current dir
fnmatch.filter(os.listdir(path), pattern)

In [3]: fnmatch.filter(os.listdir(path), pattern)
Out[3]: ['wsgi.py', 'manage.py', 'tasks.py']

Variante 2.2 – Suche rekursiv

# lookup recursive
for dirpath, dirnames, filenames in os.walk(path):

    if not filenames:
        continue

    pythonic_files = fnmatch.filter(filenames, pattern)
    if pythonic_files:
        for file in pythonic_files:
            print('{}/{}'.format(dirpath, file))

Ergebnis

./wsgi.py
./manage.py
./tasks.py
./temp/temp.py
./apps/diaries/urls.py
./apps/diaries/signals.py
./apps/diaries/actions.py
./apps/diaries/querysets.py
./apps/library/tests/test_forms.py
./apps/library/migrations/0001_initial.py
./apps/polls/views.py
./apps/polls/formsets.py
./apps/polls/reports.py
./apps/polls/admin.py

Lösung 3 – Verwenden Sie “pathlib”

# lookup in current dir
path_ = pathlib.Path('.')
tuple(path_.glob(pattern))

# lookup recursive
tuple(path_.rglob(pattern))

Anmerkungen:

  1. Getestet auf Python 3.4
  2. Das Modul „pathlib“ wurde erst in Python 3.4 hinzugefügt
  3. Python 3.5 hat eine Funktion für die rekursive Suche mit glob.glob hinzugefügt
    https://docs.python.org/3.5/library/glob.html#glob.glob. Da auf meinem Rechner Python 3.4 installiert ist, habe ich das nicht getestet.

1647534970 831 Erhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis
Gemeinschaft

Verwenden Sie os.walk, um Ihre Dateien rekursiv aufzulisten

import os
root = "/home"
pattern = "145992"
alist_filter = ['jpg','bmp','png','gif'] 
path=os.path.join(root,"mydir_to_scan")
for r,d,f in os.walk(path):
    for file in f:
        if file[-3:] in alist_filter and pattern in file:
            print os.path.join(root,file)

  • Keine Notwendigkeit zu schneiden; file.endswith(alist_filter) reicht.

    – Martijn Pieters

    8. Oktober 2015 um 7:10 Uhr

  • Wir müssen verwenden any(file.endswith(filter) for filter in alist_filter) als endswith() erlaubt keine Liste als Parameter.

    – avni hirpara

    9. November 2020 um 3:34 Uhr

1005060cookie-checkErhalten Sie eine gefilterte Liste von Dateien in einem Verzeichnis

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy