it-swarm.com.de

Holen Sie sich eine gefilterte Liste von Dateien in einem Verzeichnis

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

Was ich im Grunde will, 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 integrierte Methode gibt, denke ich derzeit daran, eine for-Schleife zu schreiben, um die Ergebnisse einer os.listdir() zu durchlaufen und alle passenden Dateien an eine neue Liste anzuhängen.

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

203
mhost
296

glob.glob() ist definitiv der richtige Weg (wie von Ignacio). Wenn Sie jedoch ein komplizierteres Matching benötigen, können Sie dies mit einem Listenverständnis und re.match() tun, etwa so

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

Flexibler, aber wie Sie feststellen, weniger effizient.

102
Ben Hoyt

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 von Listenverständnissen, weil sie auf Englisch gut lesbar ist.

Ich las die vierte Zeile als: Geben Sie mir für jedes Fn in os.listdir für meinen Pfad nur die an, die mit einer meiner enthaltenen Erweiterungen übereinstimmen.

Für Anfänger mit Python-Programmierern kann es schwierig sein, sich wirklich an das Verwenden von Listenkomplexen zum Filtern zu gewöhnen, und es kann etwas Speicheraufwand für sehr große Datensätze haben. Beim Auflisten eines Verzeichnisses und anderer einfacher String-Filteraufgaben führen Listenkomplexe jedoch zu mehr Sauberkeit dokumentierbarer Code.

Das einzige an diesem Design ist, dass es Sie nicht vor dem Fehler schützt, eine Zeichenfolge anstelle einer Liste zu übergeben. Wenn Sie z. B. versehentlich eine Zeichenfolge in eine Liste konvertieren und am Ende alle Zeichen einer Zeichenfolge prüfen, kann dies dazu führen, dass eine Reihe von falschen Positiven angezeigt wird.

Es ist jedoch besser, ein Problem zu haben, das leicht zu beheben ist, als eine Lösung, die schwer zu verstehen ist.

35
ramsey0

Andere Option:

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

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

29
Risadinha

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)
8
ghostdog74

Vorläufiger Code

import glob
import fnmatch
import pathlib
import os

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

Lösung 1 - benutze "glob"

# lookup in current dir
glob.glob(pattern)

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

Lösung 2 - benutze "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 - benutze "pathlib"

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

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

Anmerkungen:

  1. Getestet mit dem Python 3.4
  2. Das Modul "pathlib" wurde nur in Python 3.4 hinzugefügt
  3. Python 3.5 fügte eine Funktion für die rekursive Suche mit glob.glob https://docs.python.org/3.5/library/glob.html#glob.glob hinzu. Da mein Rechner mit Python 3.4 installiert ist, habe ich das nicht getestet.
7
Seti Volkylany

Filter mit glob Modul:

Glob importieren

import glob

Wild Cards:

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 einzelnes Zeichen

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

Nummernbereiche

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

Alphabet-Bereiche

glob.glob("/home/ach/[a-c]*")
4
pink.slash
import os

dir="/path/to/dir"
[x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]

Dadurch erhalten Sie eine Liste der JPG-Dateien mit ihrem vollständigen Pfad. Sie können x[0]+"/"+f durch f nur für Dateinamen ersetzen. Sie können auch f.endswith(".jpg") durch eine beliebige Zeichenfolge ersetzen, die Sie wünschen.

2
EvgenijM86

vielleicht möchten Sie auch einen Ansatz auf höherer Ebene (ich habe als findtools implementiert):

from findtools.find_files import (find_files, Match)


# Recursively find all *.txt files in **/home/**
txt_files_pattern = Match(filetype='f', name='*.txt')
found_files = find_files(path='/home', match=txt_files_pattern)

for found_file in found_files:
    print found_file

kann mit installiert werden

pip install findtools
2

Dateinamen mit den Erweiterungen "jpg" und "png" in "path/to/images":

import os
accepted_extensions = ["jpg", "png"]
filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]
1
gypsy

Sie können subprocess.check_ouput () als verwenden

import subprocess

list_files = subprocess.check_output("ls 145992*.jpg", Shell=True) 

Natürlich kann die Zeichenfolge zwischen Anführungszeichen alles sein, was Sie in der Shell ausführen möchten, und die Ausgabe speichern.

0
David A.