Wie kann ich alle Dateien eines Verzeichnisses in Python auflisten und zu einem hinzufügen list
?
Wie kann ich alle Dateien eines Verzeichnisses in Python auflisten und zu einem hinzufügen list
?
Antworten:
os.listdir()
Sie erhalten alles, was sich in einem Verzeichnis befindet - Dateien und Verzeichnisse .
Wenn Sie nur Dateien möchten , können Sie diese entweder nach unten filtern os.path
:
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
oder Sie können verwenden, os.walk()
was zwei Listen für jedes Verzeichnis ergibt, das es besucht - Aufteilen in Dateien und Verzeichnisse für Sie. Wenn Sie nur das oberste Verzeichnis wollen, können Sie es einfach beim ersten Mal brechen
from os import walk
f = []
for (dirpath, dirnames, filenames) in walk(mypath):
f.extend(filenames)
break
(_, _, filenames) = walk(mypath).next()
(wenn Sie sicher sind, dass der Spaziergang mindestens einen Wert
f.extend(filenames)
ist eigentlich nicht gleichbedeutend mit f = f + filenames
. extend
wird f
an Ort und Stelle geändert, während durch Hinzufügen eine neue Liste an einem neuen Speicherort erstellt wird. Dies bedeutet extend
im Allgemeinen effizienter als +
, kann jedoch manchmal zu Verwirrung führen, wenn mehrere Objekte Verweise auf die Liste enthalten. Schließlich ist es erwähnenswert, dass f += filenames
dies nicht gleichbedeutend f.extend(filenames)
ist . f = f + filenames
_, _, filenames = next(walk(mypath), (None, None, []))
(_, _, filenames) = next(os.walk(mypath))
Ich bevorzuge die Verwendung des glob
Moduls, da es Mustervergleich und -erweiterung durchführt.
import glob
print(glob.glob("/home/adam/*.txt"))
Es wird eine Liste mit den abgefragten Dateien zurückgegeben:
['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
/home/user/foo/bar/hello.txt
, dann, wenn im Verzeichnis ausgeführt wird foo
, die glob("bar/*.txt")
angezeigt werden kann bar/hello.txt
. Es gibt Fälle, in denen Sie tatsächlich den vollständigen (dh absoluten) Pfad möchten. Für diese Fälle siehe stackoverflow.com/questions/51520/…
glob.glob("*")
würde.
x=glob.glob("../train/*.png")
werde mir eine Reihe meiner Pfade geben, solange ich den Namen des Ordners kenne. So cool!
Holen Sie sich eine Liste der Dateien mit Python 2 und 3
os.listdir()
So erhalten Sie alle Dateien (und Verzeichnisse) im aktuellen Verzeichnis (Python 3)
Im Folgenden finden Sie einfache Methoden zum Abrufen nur von Dateien im aktuellen Verzeichnis mithilfe von os
und der listdir()
Funktion in Python 3. Weitere Untersuchungen zeigen, wie Ordner im Verzeichnis zurückgegeben werden. Sie haben die Datei jedoch nicht im Unterverzeichnis kann zu Fuß gehen (später besprochen).
import os
arr = os.listdir()
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
glob
Ich fand glob einfacher, die Datei des gleichen Typs oder mit etwas gemeinsamem auszuwählen. Schauen Sie sich das folgende Beispiel an:
import glob
txtfiles = []
for file in glob.glob("*.txt"):
txtfiles.append(file)
glob
mit Listenverständnis
import glob
mylist = [f for f in glob.glob("*.txt")]
glob
mit einer Funktion
Die Funktion gibt eine Liste der angegebenen Erweiterung (.txt, .docx ecc.) Im Argument zurück
import glob
def filebrowser(ext=""):
"Returns files with an extension"
return [f for f in glob.glob(f"*{ext}")]
x = filebrowser(".txt")
print(x)
>>> ['example.txt', 'fb.txt', 'intro.txt', 'help.txt']
glob
Erweiterung des vorherigen Codes
Die Funktion gibt jetzt eine Liste der Dateien zurück, die mit der Zeichenfolge übereinstimmen, die Sie als Argument übergeben
import glob
def filesearch(word=""):
"""Returns a list with all files with the word/extension in it"""
file = []
for f in glob.glob("*"):
if word[0] == ".":
if f.endswith(word):
file.append(f)
return file
elif word in f:
file.append(f)
return file
return file
lookfor = "example", ".py"
for w in lookfor:
print(f"{w:10} found => {filesearch(w)}")
Ausgabe
example found => []
.py found => ['search.py']
Den vollständigen Pfadnamen mit abrufen
os.path.abspath
Wie Sie bemerkt haben, haben Sie im obigen Code nicht den vollständigen Pfad der Datei. Wenn Sie den absoluten Pfad benötigen, können Sie eine andere Funktion des os.path
aufgerufenen Moduls verwenden _getfullpathname
und die Datei, aus der Sie sie erhalten, os.listdir()
als Argument verwenden. Es gibt andere Möglichkeiten, den vollständigen Pfad zu erhalten, wie wir später überprüfen werden (ich habe, wie von mexmex vorgeschlagen, _getfullpathname durch ersetzt abspath
).
import os
files_path = [os.path.abspath(x) for x in os.listdir()]
print(files_path)
>>> ['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']
Holen Sie sich den vollständigen Pfadnamen eines Dateityps in alle Unterverzeichnisse mit
walk
Ich finde das sehr nützlich, um Dinge in vielen Verzeichnissen zu finden, und es hat mir geholfen, eine Datei zu finden, an die ich mich nicht erinnern konnte:
import os
# Getting the current work directory (cwd)
thisdir = os.getcwd()
# r=root, d=directories, f = files
for r, d, f in os.walk(thisdir):
for file in f:
if file.endswith(".docx"):
print(os.path.join(r, file))
os.listdir()
: Dateien im aktuellen Verzeichnis abrufen (Python 2)
Wenn Sie in Python 2 die Liste der Dateien im aktuellen Verzeichnis anzeigen möchten, müssen Sie das Argument '.' oder os.getcwd () in der Methode os.listdir.
import os
arr = os.listdir('.')
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
In den Verzeichnisbaum aufsteigen
# Method 1
x = os.listdir('..')
# Method 2
x= os.listdir('/')
Dateien abrufen:
os.listdir()
in einem bestimmten Verzeichnis (Python 2 und 3)
import os
arr = os.listdir('F:\\python')
print(arr)
>>> ['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
Holen Sie sich Dateien eines bestimmten Unterverzeichnisses mit
os.listdir()
import os
x = os.listdir("./content")
os.walk('.')
- Aktuelles Verzeichnis
import os
arr = next(os.walk('.'))[2]
print(arr)
>>> ['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']
next(os.walk('.'))
undos.path.join('dir', 'file')
import os
arr = []
for d,r,f in next(os.walk("F:\\_python")):
for file in f:
arr.append(os.path.join(r,file))
for f in arr:
print(files)
>>> F:\\_python\\dict_class.py
>>> F:\\_python\\programmi.txt
next(os.walk('F:\\')
- Holen Sie sich den vollständigen Pfad - Listenverständnis
[os.path.join(r,file) for r,d,f in next(os.walk("F:\\_python")) for file in f]
>>> ['F:\\_python\\dict_class.py', 'F:\\_python\\programmi.txt']
os.walk
- Vollständigen Pfad abrufen - Alle Dateien in Unterverzeichnissen **
x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]
print(x)
>>> ['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']
os.listdir()
- Holen Sie sich nur TXT-Dateien
arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
print(arr_txt)
>>> ['work.txt', '3ebooks.txt']
Verwenden Sie
glob
, um den vollständigen Pfad der Dateien abzurufen
Wenn ich den absoluten Pfad der Dateien benötigen sollte:
from path import path
from glob import glob
x = [path(f).abspath() for f in glob("F:\\*.txt")]
for f in x:
print(f)
>>> F:\acquistionline.txt
>>> F:\acquisti_2018.txt
>>> F:\bootstrap_jquery_ecc.txt
Verwenden
os.path.isfile
, um Verzeichnisse in der Liste zu vermeiden
import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)
>>> ['a simple game.py', 'data.txt', 'decorator.py']
Verwenden
pathlib
von Python 3.4
import pathlib
flist = []
for p in pathlib.Path('.').iterdir():
if p.is_file():
print(p)
flist.append(p)
>>> error.PNG
>>> exemaker.bat
>>> guiprova.mp3
>>> setup.py
>>> speak_gui2.py
>>> thumb.PNG
Mit list comprehension
:
flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]
Alternativ können Sie pathlib.Path()
anstelle von verwendenpathlib.Path(".")
Verwenden Sie die glob-Methode in pathlib.Path ()
import pathlib
py = pathlib.Path().glob("*.py")
for file in py:
print(file)
>>> stack_overflow_list.py
>>> stack_overflow_list_tkinter.py
Holen Sie sich alle und nur Dateien mit os.walk
import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
for f in t:
y.append(f)
print(y)
>>> ['append_to_list.py', 'data.txt', 'data1.txt', 'data2.txt', 'data_180617', 'os_walk.py', 'READ2.py', 'read_data.py', 'somma_defaltdic.py', 'substitute_words.py', 'sum_data.py', 'data.txt', 'data1.txt', 'data_180617']
Holen Sie sich nur Dateien mit next und gehen Sie in ein Verzeichnis
import os
x = next(os.walk('F://python'))[2]
print(x)
>>> ['calculator.bat','calculator.py']
Holen Sie sich nur Verzeichnisse mit next und gehen Sie in ein Verzeichnis
import os
next(os.walk('F://python'))[1] # for the current dir use ('.')
>>> ['python3','others']
Holen Sie sich alle Unterverzeichnisnamen mit
walk
for r,d,f in os.walk("F:\\_python"):
for dirs in d:
print(dirs)
>>> .vscode
>>> pyexcel
>>> pyschool.py
>>> subtitles
>>> _metaprogramming
>>> .ipynb_checkpoints
os.scandir()
ab Python 3.5 und höher
import os
x = [f.name for f in os.scandir() if f.is_file()]
print(x)
>>> ['calculator.bat','calculator.py']
# Another example with scandir (a little variation from docs.python.org)
# This one is more efficient than os.listdir.
# In this case, it shows the files only in the current directory
# where the script is executed.
import os
with os.scandir() as i:
for entry in i:
if entry.is_file():
print(entry.name)
>>> ebookmaker.py
>>> error.PNG
>>> exemaker.bat
>>> guiprova.mp3
>>> setup.py
>>> speakgui4.py
>>> speak_gui2.py
>>> speak_gui3.py
>>> thumb.PNG
Beispiele:
Ex. 1: Wie viele Dateien befinden sich in den Unterverzeichnissen?
In diesem Beispiel suchen wir nach der Anzahl der Dateien, die in allen Verzeichnissen und deren Unterverzeichnissen enthalten sind.
import os
def count(dir, counter=0):
"returns number of files in dir and subdirs"
for pack in os.walk(dir):
for f in pack[2]:
counter += 1
return dir + " : " + str(counter) + "files"
print(count("F:\\python"))
>>> 'F:\\\python' : 12057 files'
Beispiel 2: Wie kopiere ich alle Dateien von einem Verzeichnis in ein anderes?
Ein Skript, mit dem Sie auf Ihrem Computer alle Dateien eines Typs (Standard: pptx) suchen und in einen neuen Ordner kopieren können.
import os
import shutil
from path import path
destination = "F:\\file_copied"
# os.makedirs(destination)
def copyfile(dir, filetype='pptx', counter=0):
"Searches for pptx (or other - pptx is the default) files and copies them"
for pack in os.walk(dir):
for f in pack[2]:
if f.endswith(filetype):
fullpath = pack[0] + "\\" + f
print(fullpath)
shutil.copy(fullpath, destination)
counter += 1
if counter > 0:
print('-' * 30)
print("\t==> Found in: `" + dir + "` : " + str(counter) + " files\n")
for dir in os.listdir():
"searches for folders that starts with `_`"
if dir[0] == '_':
# copyfile(dir, filetype='pdf')
copyfile(dir, filetype='txt')
>>> _compiti18\Compito Contabilità 1\conti.txt
>>> _compiti18\Compito Contabilità 1\modula4.txt
>>> _compiti18\Compito Contabilità 1\moduloa4.txt
>>> ------------------------
>>> ==> Found in: `_compiti18` : 3 files
Ex. 3: So erhalten Sie alle Dateien in einer txt-Datei
Falls Sie eine txt-Datei mit allen Dateinamen erstellen möchten:
import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
for eachfile in os.listdir():
mylist += eachfile + "\n"
file.write(mylist)
Beispiel: txt mit allen Dateien einer Festplatte
"""
We are going to save a txt file with all the files in your directory.
We will use the function walk()
"""
import os
# see all the methods of os
# print(*dir(os), sep=", ")
listafile = []
percorso = []
with open("lista_file.txt", "w", encoding='utf-8') as testo:
for root, dirs, files in os.walk("D:\\"):
for file in files:
listafile.append(file)
percorso.append(root + "\\" + file)
testo.write(file + "\n")
listafile.sort()
print("N. of files", len(listafile))
with open("lista_file_ordinata.txt", "w", encoding="utf-8") as testo_ordinato:
for file in listafile:
testo_ordinato.write(file + "\n")
with open("percorso.txt", "w", encoding="utf-8") as file_percorso:
for file in percorso:
file_percorso.write(file + "\n")
os.system("lista_file.txt")
os.system("lista_file_ordinata.txt")
os.system("percorso.txt")
Die gesamte Datei von C: \ in einer Textdatei
Dies ist eine kürzere Version des vorherigen Codes. Ändern Sie den Ordner, in dem die Dateien gesucht werden sollen, wenn Sie von einer anderen Position aus starten müssen. Dieser Code generiert eine 50-MB-Textdatei auf meinem Computer mit weniger als 500.000 Zeilen mit Dateien mit dem vollständigen Pfad.
import os
with open("file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk("C:\\"):
for file in f:
filewrite.write(f"{r + file}\n")
So schreiben Sie eine Datei mit allen Pfaden in einen Ordner eines Typs
Mit dieser Funktion können Sie eine txt-Datei erstellen, die den Namen eines Dateityps enthält, nach dem Sie suchen (z. B. pngfile.txt), und den vollständigen Pfad aller Dateien dieses Typs enthält. Es kann manchmal nützlich sein, denke ich.
import os
def searchfiles(extension='.ttf', folder='H:\\'):
"Create a txt file with all the file of a type"
with open(extension[1:] + "file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk(folder):
for file in f:
if file.endswith(extension):
filewrite.write(f"{r + file}\n")
# looking for png file (fonts) in the hard disk H:\
searchfiles('.png', 'H:\\')
>>> H:\4bs_18\Dolphins5.png
>>> H:\4bs_18\Dolphins6.png
>>> H:\4bs_18\Dolphins7.png
>>> H:\5_18\marketing html\assets\imageslogo2.png
>>> H:\7z001.png
>>> H:\7z002.png
(Neu) Finde alle Dateien und öffne sie mit der tkinter GUI
Ich wollte in diesem Jahr 2019 nur eine kleine App hinzufügen, um nach allen Dateien in einem Verzeichnis zu suchen und sie durch Doppelklicken auf den Namen der Datei in der Liste öffnen zu können.
import tkinter as tk
import os
def searchfiles(extension='.txt', folder='H:\\'):
"insert all files in the listbox"
for r, d, f in os.walk(folder):
for file in f:
if file.endswith(extension):
lb.insert(0, r + "\\" + file)
def open_file():
os.startfile(lb.get(lb.curselection()[0]))
root = tk.Tk()
root.geometry("400x400")
bt = tk.Button(root, text="Search", command=lambda:searchfiles('.png', 'H:\\'))
bt.pack()
lb = tk.Listbox(root)
lb.pack(fill="both", expand=1)
lb.bind("<Double-Button>", lambda x: open_file())
root.mainloop()
import os
os.listdir("somedirectory")
gibt eine Liste aller Dateien und Verzeichnisse in "somedirectory" zurück.
glob.glob
os.listdir()
immer nur Dateinamen zurück (keine relativen Pfade). Was glob.glob()
zurückkehrt, hängt vom Pfadformat des Eingabemusters ab.
Eine einzeilige Lösung, um nur eine Liste von Dateien (keine Unterverzeichnisse) abzurufen:
filenames = next(os.walk(path))[2]
oder absolute Pfadnamen:
paths = [os.path.join(path, fn) for fn in next(os.walk(path))[2]]
import os
. Scheint weniger prägnant als glob()
für mich.
glob()
würde es als Datei behandeln. Ihre Methode würde es als Verzeichnis behandeln.
Abrufen vollständiger Dateipfade aus einem Verzeichnis und allen seinen Unterverzeichnissen
import os
def get_filepaths(directory):
"""
This function will generate the file names in a directory
tree by walking the tree either top-down or bottom-up. For each
directory in the tree rooted at directory top (including top itself),
it yields a 3-tuple (dirpath, dirnames, filenames).
"""
file_paths = [] # List which will store all of the full filepaths.
# Walk the tree.
for root, directories, files in os.walk(directory):
for filename in files:
# Join the two strings in order to form the full filepath.
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths # Self-explanatory.
# Run the above function and store its results in a variable.
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")
print full_file_paths
welches die Liste druckt:
['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
Wenn Sie möchten, können Sie den Inhalt öffnen und lesen oder sich nur auf Dateien mit der Erweiterung ".dat" konzentrieren, wie im folgenden Code beschrieben:
for f in full_file_paths:
if f.endswith(".dat"):
print f
/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat
Seit Version 3.4 gibt es dafür eingebaute Iteratoren, die viel effizienter sind als os.listdir()
:
pathlib
: Neu in Version 3.4.
>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]
Gemäß PEP 428 besteht das Ziel der pathlib
Bibliothek darin, eine einfache Hierarchie von Klassen bereitzustellen, um Dateisystempfade und die allgemeinen Operationen, die Benutzer über sie ausführen, zu handhaben.
os.scandir()
: Neu in Version 3.5.
>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]
Beachten Sie, dass os.walk()
verwendet os.scandir()
statt os.listdir()
von 2-20 mal nach erhöht wurde von Version 3.5, und seine Geschwindigkeit 471 PEP .
Lassen Sie mich auch empfehlen, den Kommentar von ShadowRanger unten zu lesen.
list
. Könnte alternativ p.name
anstelle der ersten verwendet werden, p
wenn dies bevorzugt wird.
pathlib.Path()
Instanzen zu da sie viele nützliche Methoden haben, mit denen ich keinen Abfall verschwenden möchte. Sie können str(p)
sie auch für Pfadnamen aufrufen .
os.scandir
Lösung ist effizienter als os.listdir
bei einer os.path.is_file
Prüfung oder Ähnlichem, selbst wenn Sie eine benötigen list
(damit Sie nicht von einer verzögerten Iteration profitieren), da os.scandir
vom Betriebssystem bereitgestellte APIs verwendet werden, mit denen Sie die is_file
Informationen während der Iteration kostenlos erhalten , überhaupt kein Roundtrip pro Datei auf die Festplatte zu stat
ihnen (unter Windows DirEntry
erhalten Sie stat
kostenlos vollständige Informationen, auf * NIX-Systemen, die stat
für weitere Informationen erforderlich sindis_file
, is_dir
usw., aber DirEntry
Caches auf den ersten der stat
Einfachheit halber).
entry.name
nur den Dateinamen oder entry.path
den vollständigen Pfad abrufen. Nicht mehr überall os.path.join ().
Als die Frage gestellt wurde, stelle ich mir vor, dass Python 2 die LTS- Version war, die Codebeispiele werden jedoch von Python 3 ( .5 ) ausgeführt (ich werde sie so Python 2- konform wie möglich halten; auch jeden dazugehörigen Code Python , das ich veröffentlichen werde, stammt aus Version 3.5.4 (sofern nicht anders angegeben). Dies hat Konsequenzen im Zusammenhang mit einem anderen Schlüsselwort in der Frage: " Fügen Sie sie einer Liste hinzu ":
>>> import sys >>> sys.version '2.7.10 (default, Mar 8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)]' >>> m = map(lambda x: x, [1, 2, 3]) # Just a dummy lambda function >>> m, type(m) ([1, 2, 3], <type 'list'>) >>> len(m) 3
>>> import sys >>> sys.version '3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]' >>> m = map(lambda x: x, [1, 2, 3]) >>> m, type(m) (<map object at 0x000001B4257342B0>, <class 'map'>) >>> len(m) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'map' has no len() >>> lm0 = list(m) # Build a list from the generator >>> lm0, type(lm0) ([1, 2, 3], <class 'list'>) >>> >>> lm1 = list(m) # Build a list from the same generator >>> lm1, type(lm1) # Empty list now - generator already consumed ([], <class 'list'>)
Die Beispiele basieren auf einem Verzeichnis namens root_dir mit der folgenden Struktur (dieses Beispiel ist für Win , aber ich verwende denselben Baum auch auf Lnx ):
E:\Work\Dev\StackOverflow\q003207219>tree /f "root_dir" Folder PATH listing for volume Work Volume serial number is 00000029 3655:6FED E:\WORK\DEV\STACKOVERFLOW\Q003207219\ROOT_DIR ¦ file0 ¦ file1 ¦ +---dir0 ¦ +---dir00 ¦ ¦ ¦ file000 ¦ ¦ ¦ ¦ ¦ +---dir000 ¦ ¦ file0000 ¦ ¦ ¦ +---dir01 ¦ ¦ file010 ¦ ¦ file011 ¦ ¦ ¦ +---dir02 ¦ +---dir020 ¦ +---dir0200 +---dir1 ¦ file10 ¦ file11 ¦ file12 ¦ +---dir2 ¦ ¦ file20 ¦ ¦ ¦ +---dir20 ¦ file200 ¦ +---dir3
[Python 3]: os. listdir ( path = '.' )
Gibt eine Liste mit den Namen der Einträge in dem durch path angegebenen Verzeichnis zurück. Die Liste ist in beliebiger Reihenfolge und enthält keine speziellen Einträge
'.'
und'..'
...
>>> import os >>> root_dir = "root_dir" # Path relative to current dir (os.getcwd()) >>> >>> os.listdir(root_dir) # List all the items in root_dir ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))] # Filter items and only keep files (strip out directories) ['file0', 'file1']
Ein ausführlicheres Beispiel ( code_os_listdir.py ):
import os
from pprint import pformat
def _get_dir_content(path, include_folders, recursive):
entries = os.listdir(path)
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
yield entry_with_path
if recursive:
for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
yield sub_entry
else:
yield entry_with_path
def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
for item in _get_dir_content(path, include_folders, recursive):
yield item if prepend_folder_name else item[path_len:]
def _get_dir_content_old(path, include_folders, recursive):
entries = os.listdir(path)
ret = list()
for entry in entries:
entry_with_path = os.path.join(path, entry)
if os.path.isdir(entry_with_path):
if include_folders:
ret.append(entry_with_path)
if recursive:
ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
else:
ret.append(entry_with_path)
return ret
def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
path_len = len(path) + len(os.path.sep)
return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
def main():
root_dir = "root_dir"
ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
lret0 = list(ret0)
print(ret0, len(lret0), pformat(lret0))
ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
print(len(ret1), pformat(ret1))
if __name__ == "__main__":
main()
Anmerkungen :
Ausgabe :
(py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py" <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0', 'root_dir\\dir0\\dir00', 'root_dir\\dir0\\dir00\\dir000', 'root_dir\\dir0\\dir00\\dir000\\file0000', 'root_dir\\dir0\\dir00\\file000', 'root_dir\\dir0\\dir01', 'root_dir\\dir0\\dir01\\file010', 'root_dir\\dir0\\dir01\\file011', 'root_dir\\dir0\\dir02', 'root_dir\\dir0\\dir02\\dir020', 'root_dir\\dir0\\dir02\\dir020\\dir0200', 'root_dir\\dir1', 'root_dir\\dir1\\file10', 'root_dir\\dir1\\file11', 'root_dir\\dir1\\file12', 'root_dir\\dir2', 'root_dir\\dir2\\dir20', 'root_dir\\dir2\\dir20\\file200', 'root_dir\\dir2\\file20', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] 11 ['dir0\\dir00\\dir000\\file0000', 'dir0\\dir00\\file000', 'dir0\\dir01\\file010', 'dir0\\dir01\\file011', 'dir1\\file10', 'dir1\\file11', 'dir1\\file12', 'dir2\\dir20\\file200', 'dir2\\file20', 'file0', 'file1']
[Python 3]: os. scandir ( path = '.' ) ( Python 3.5 +, Backport: [PyPI]: scandir )
Gibt einen Iterator von os.DirEntry- Objekten zurück, der den Einträgen in dem durch path angegebenen Verzeichnis entspricht . Die Einträge werden in beliebiger Reihenfolge und die speziellen Einträge ausgegeben
'.'
und'..'
sind nicht enthalten.Die Verwendung von scandir () anstelle von listdir () kann die Leistung von Code, der auch Dateityp- oder Dateiattributinformationen benötigt, erheblich verbessern , da os.DirEntry- Objekte diese Informationen verfügbar machen , wenn das Betriebssystem sie beim Scannen eines Verzeichnisses bereitstellt. Alle os.DirEntry- Methoden führen möglicherweise einen Systemaufruf aus, aber is_dir () und is_file () erfordern normalerweise nur einen Systemaufruf für symbolische Links. os.DirEntry.stat () erfordert unter Unix immer einen Systemaufruf, unter Windows jedoch nur einen für symbolische Links.
>>> import os >>> root_dir = os.path.join(".", "root_dir") # Explicitly prepending current directory >>> root_dir '.\\root_dir' >>> >>> scandir_iterator = os.scandir(root_dir) >>> scandir_iterator <nt.ScandirIterator object at 0x00000268CF4BC140> >>> [item.path for item in scandir_iterator] ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1'] >>> >>> [item.path for item in scandir_iterator] # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension) [] >>> >>> scandir_iterator = os.scandir(root_dir) # Reinitialize the generator >>> for item in scandir_iterator : ... if os.path.isfile(item.path): ... print(item.name) ... file0 file1
Anmerkungen :
os.listdir
[Python 3]: os. walk ( top, topdown = True, onerror = None, followlinks = False )
Generieren Sie die Dateinamen in einem Verzeichnisbaum, indem Sie den Baum entweder von oben nach unten oder von unten nach oben durchlaufen. Für jedes Verzeichnis in dem Verzeichnisbaum am wurzelt oben (einschließlich der oben selbst), es ergibt sich ein 3-Tupel (
dirpath
,dirnames
,filenames
).
>>> import os >>> root_dir = os.path.join(os.getcwd(), "root_dir") # Specify the full path >>> root_dir 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir' >>> >>> walk_generator = os.walk(root_dir) >>> root_dir_entry = next(walk_generator) # First entry corresponds to the root dir (passed as an argument) >>> root_dir_entry ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1']) >>> >>> root_dir_entry[1] + root_dir_entry[2] # Display dirs and files (direct descendants) in a single list ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]] # Display all the entries in the previous list by their full path ['E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\file1'] >>> >>> for entry in walk_generator: # Display the rest of the elements (corresponding to every subdir) ... print(entry) ... ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], []) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2', ['dir20'], ['file20']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir2\\dir20', [], ['file200']) ('E:\\Work\\Dev\\StackOverflow\\q003207219\\root_dir\\dir3', [], [])
Anmerkungen :
os.scandir
( os.listdir
bei älteren Versionen)[Python 3]: glob. glob ( Pfadname, *, rekursiv = falsch ) ( [Python 3]: glob. iglob ( Pfadname, *, rekursiv = falsch ) )
Gibt eine möglicherweise leere Liste von Pfadnamen zurück , die mit dem Pfadnamen übereinstimmen. Dies muss eine Zeichenfolge sein, die eine Pfadspezifikation enthält. Der Pfadname kann entweder absolut (wie
/usr/src/Python-1.5/Makefile
) oder relativ (wie../../Tools/*/*.gif
) sein und Platzhalter im Shell-Stil enthalten. Unterbrochene Symlinks sind in den Ergebnissen enthalten (wie in der Shell).
...
geändert in Version 3.5 : Unterstützung für rekursive Globs mit "**
".
>>> import glob, os >>> wildcard_pattern = "*" >>> root_dir = os.path.join("root_dir", wildcard_pattern) # Match every file/dir name >>> root_dir 'root_dir\\*' >>> >>> glob_list = glob.glob(root_dir) >>> glob_list ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1'] >>> >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list] # Strip the dir name and the path separator from begining ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> for entry in glob.iglob(root_dir + "*", recursive=True): ... print(entry) ... root_dir\ root_dir\dir0 root_dir\dir0\dir00 root_dir\dir0\dir00\dir000 root_dir\dir0\dir00\dir000\file0000 root_dir\dir0\dir00\file000 root_dir\dir0\dir01 root_dir\dir0\dir01\file010 root_dir\dir0\dir01\file011 root_dir\dir0\dir02 root_dir\dir0\dir02\dir020 root_dir\dir0\dir02\dir020\dir0200 root_dir\dir1 root_dir\dir1\file10 root_dir\dir1\file11 root_dir\dir1\file12 root_dir\dir2 root_dir\dir2\dir20 root_dir\dir2\dir20\file200 root_dir\dir2\file20 root_dir\dir3 root_dir\file0 root_dir\file1
Anmerkungen :
os.listdir
[Python 3]: Klassenpfad. Pfad ( * Pfadsegmente ) ( Python 3.4 +, Backport: [PyPI]: pathlib2 )
>>> import pathlib >>> root_dir = "root_dir" >>> root_dir_instance = pathlib.Path(root_dir) >>> root_dir_instance WindowsPath('root_dir') >>> root_dir_instance.name 'root_dir' >>> root_dir_instance.is_dir() True >>> >>> [item.name for item in root_dir_instance.glob("*")] # Wildcard searching for all direct descendants ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()] # Display paths (including parent) for files only ['root_dir\\file0', 'root_dir\\file1']
Anmerkungen :
[Python 2]: dircache.listdir (Pfad) (nur Python 2 )
os.listdir
mit Cachingdef listdir(path):
"""List directory contents, using cache."""
try:
cached_mtime, list = cache[path]
del cache[path]
except KeyError:
cached_mtime, list = -1, []
mtime = os.stat(path).st_mtime
if mtime != cached_mtime:
list = os.listdir(path)
list.sort()
cache[path] = mtime, list
return list
[man7]: OPENDIR (3) / [man7]: READDIR (3) / [man7]: CLOSEDIR (3) über [Python 3]: ctypes - Eine Fremdfunktionsbibliothek für Python ( POSIX- spezifisch)
ctypes ist eine Fremdfunktionsbibliothek für Python. Es bietet C-kompatible Datentypen und ermöglicht das Aufrufen von Funktionen in DLLs oder gemeinsam genutzten Bibliotheken. Es kann verwendet werden, um diese Bibliotheken in reines Python zu verpacken.
code_ctypes.py :
#!/usr/bin/env python3
import sys
from ctypes import Structure, \
c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \
CDLL, POINTER, \
create_string_buffer, get_errno, set_errno, cast
DT_DIR = 4
DT_REG = 8
char256 = c_char * 256
class LinuxDirent64(Structure):
_fields_ = [
("d_ino", c_ulonglong),
("d_off", c_longlong),
("d_reclen", c_ushort),
("d_type", c_ubyte),
("d_name", char256),
]
LinuxDirent64Ptr = POINTER(LinuxDirent64)
libc_dll = this_process = CDLL(None, use_errno=True)
# ALWAYS set argtypes and restype for functions, otherwise it's UB!!!
opendir = libc_dll.opendir
readdir = libc_dll.readdir
closedir = libc_dll.closedir
def get_dir_content(path):
ret = [path, list(), list()]
dir_stream = opendir(create_string_buffer(path.encode()))
if (dir_stream == 0):
print("opendir returned NULL (errno: {:d})".format(get_errno()))
return ret
set_errno(0)
dirent_addr = readdir(dir_stream)
while dirent_addr:
dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr)
dirent = dirent_ptr.contents
name = dirent.d_name.decode()
if dirent.d_type & DT_DIR:
if name not in (".", ".."):
ret[1].append(name)
elif dirent.d_type & DT_REG:
ret[2].append(name)
dirent_addr = readdir(dir_stream)
if get_errno():
print("readdir returned NULL (errno: {:d})".format(get_errno()))
closedir(dir_stream)
return ret
def main():
print("{:s} on {:s}\n".format(sys.version, sys.platform))
root_dir = "root_dir"
entries = get_dir_content(root_dir)
print(entries)
if __name__ == "__main__":
main()
Anmerkungen :
os.walk
Format zurück. Ich habe mich nicht darum gekümmert, es rekursiv zu machen, aber ausgehend vom vorhandenen Code wäre das eine ziemlich triviale AufgabeAusgabe :
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q003207219]> ./code_ctypes.py 3.5.2 (default, Nov 12 2018, 13:43:14) [GCC 5.4.0 20160609] on linux ['root_dir', ['dir2', 'dir1', 'dir3', 'dir0'], ['file1', 'file0']]
[ActiveState.Docs]: win32file.FindFilesW ( Win- spezifisch)
Ruft mithilfe der Windows-Unicode-API eine Liste übereinstimmender Dateinamen ab. Eine Schnittstelle zur API FindFirstFileW / FindNextFileW / Find close Funktionen.
>>> import os, win32file, win32con >>> root_dir = "root_dir" >>> wildcard = "*" >>> root_dir_wildcard = os.path.join(root_dir, wildcard) >>> entry_list = win32file.FindFilesW(root_dir_wildcard) >>> len(entry_list) # Don't display the whole content as it's too long 8 >>> [entry[-2] for entry in entry_list] # Only display the entry names ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1'] >>> >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")] # Filter entries and only display dir names (except self and parent) ['dir0', 'dir1', 'dir2', 'dir3'] >>> >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)] # Only display file "full" names ['root_dir\\file0', 'root_dir\\file1']
Anmerkungen :
win32file.FindFilesW
Teil ist [GitHub]: mhammond / pywin32 - Python für Windows (pywin32) Erweiterungen , die eine ist Python Wrapper über WINAPI sAnmerkungen :
Der Code soll tragbar (mit Ausnahme von Orten, die auf einen bestimmten Bereich abzielen - die markiert sind) oder kreuzweise sein:
In den obigen Varianten wurden mehrere Pfadstile (absolut, Verwandte) verwendet, um die Tatsache zu veranschaulichen, dass die verwendeten "Werkzeuge" in dieser Richtung flexibel sind
os.listdir
und os.scandir
benutze opendir / readdir / closedir ( [MS.Docs]: FindFirstFileW-Funktion / [MS.Docs]: FindNextFileW-Funktion / [MS.Docs]: FindClose-Funktion ) (über [GitHub]: python / cpython - (master) cpython / Module / posixmodule.c )
win32file.FindFilesW
verwendet auch diese ( Win- spezifischen) Funktionen (über [GitHub]: mhammond / pywin32 - (master) pywin32 / win32 / src / win32file.i )
_get_dir_content (ab Punkt 1 ) kann mit jedem dieser Ansätze implementiert werden (einige erfordern mehr Arbeit und andere weniger).
filter_func=lambda x: True
(dies wird nicht entfernt alles) und in _get_dir_content so etwas wie: if not filter_func(entry_with_path): continue
(Wenn die Funktion für einen Eintrag fehlschlägt, wird sie übersprungen), aber je komplexer der Code wird, desto länger dauert die AusführungNota bene! Da die Rekursion verwendet wird, muss ich erwähnen, dass ich einige Tests auf meinem Laptop ( Win 10 x64 ) durchgeführt habe, die völlig unabhängig von diesem Problem waren, und als die Rekursionsstufe Werte irgendwo im Bereich (990 .. 1000) erreichte ( Rekursionslimit - 1000) (Standard)), ich habe StackOverflow :). Wenn der Verzeichnisbaum diese Grenze überschreitet (ich bin kein FS- Experte, daher weiß ich nicht, ob dies überhaupt möglich ist), könnte dies ein Problem sein.
Ich muss auch erwähnen, dass ich nicht versucht habe, das Rekursionslimit zu erhöhen, da ich keine Erfahrung in diesem Bereich habe (wie viel kann ich erhöhen, bevor ich auch den Stack unter OS erhöhen mussLevel), aber theoretisch besteht immer die Möglichkeit eines Ausfalls, wenn die Dir-Tiefe größer ist als das höchstmögliche Rekursionslimit (auf dieser Maschine).
Die Codebeispiele dienen nur zu Demonstrationszwecken. Das bedeutet, dass ich die Fehlerbehandlung nicht berücksichtigt habe (ich glaube, es gibt keinen Versuch / außer / else / finally- Block), daher ist der Code nicht robust (der Grund ist: ihn so einfach und kurz wie möglich zu halten ). Für die Produktion sollte auch die Fehlerbehandlung hinzugefügt werden
Verwenden Sie Python nur als Wrapper
Die bekannteste Variante, die ich kenne, ist der sogenannte Systemadministrator- Ansatz:
grep
/ findstr
) oder das Formatieren der Ausgabe könnte auf beiden Seiten erfolgen, aber ich werde nicht darauf bestehen. Auch habe ich absichtlich os.system
statt subprocess.Popen
.(py35x64_test) E:\Work\Dev\StackOverflow\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")" dir0 dir1 dir2 dir3 file0 file1
Im Allgemeinen ist dieser Ansatz zu vermeiden, da der Parsing-Code ebenfalls angepasst werden sollte , wenn sich das Befehlsausgabeformat zwischen den Betriebssystemversionen / -varianten geringfügig unterscheidet . ganz zu schweigen von den Unterschieden zwischen den Gebietsschemas).
Ich wirklich mochte adamk Antwort , was darauf hindeutet , dass Sie verwenden glob()
, aus dem Modul mit dem gleichen Namen. Auf diese Weise können Sie Muster mit *
s abgleichen .
Aber wie andere Leute in den Kommentaren glob()
betonten , kann man über inkonsistente Schrägstriche stolpern. Um dies zu unterstützen, schlage ich vor, dass Sie die Funktionen join()
und expanduser()
im os.path
Modul und möglicherweise auch die getcwd()
Funktion im os
Modul verwenden.
Als Beispiele:
from glob import glob
# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')
Das Obige ist schrecklich - der Pfad wurde fest codiert und funktioniert unter Windows immer nur zwischen dem Laufwerksnamen und dem \
s, das im Pfad fest codiert ist.
from glob import glob
from os.path import join
# Return everything under Users, admin, that contains a folder called wlp.
glob(join('Users', 'admin', '*', 'wlp'))
Das Obige funktioniert besser, Users
hängt jedoch vom Ordnernamen ab, der häufig unter Windows und nicht so häufig unter anderen Betriebssystemen gefunden wird. Es hängt auch davon ab, dass der Benutzer einen bestimmten Namen hat admin
.
from glob import glob
from os.path import expanduser, join
# Return everything under the user directory that contains a folder called wlp.
glob(join(expanduser('~'), '*', 'wlp'))
Dies funktioniert perfekt auf allen Plattformen.
Ein weiteres großartiges Beispiel, das plattformübergreifend perfekt funktioniert und etwas anderes macht:
from glob import glob
from os import getcwd
from os.path import join
# Return everything under the current directory that contains a folder called wlp.
glob(join(getcwd(), '*', 'wlp'))
Ich hoffe, diese Beispiele helfen Ihnen dabei, die Leistungsfähigkeit einiger Funktionen zu erkennen, die Sie in den Standardmodulen der Python-Bibliothek finden.
**
funktioniert dies, solange Sie es einstellen recursive = True
. Siehe die Dokumente hier: docs.python.org/3.5/library/glob.html#glob.glob
def list_files(path):
# returns a list of names (with extension, without full path) of all files
# in folder path
files = []
for name in os.listdir(path):
if os.path.isfile(os.path.join(path, name)):
files.append(name)
return files
Wenn Sie nach einer Python-Implementierung von find suchen , ist dies ein Rezept, das ich ziemlich häufig verwende:
from findtools.find_files import (find_files, Match)
# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)
for found_file in found_files:
print found_file
Also habe ich ein PyPI- Paket daraus gemacht und es gibt auch ein GitHub-Repository . Ich hoffe, dass jemand es möglicherweise nützlich für diesen Code findet.
Für bessere Ergebnisse können Sie die listdir()
Methode des os
Moduls zusammen mit einem Generator verwenden (ein Generator ist ein leistungsstarker Iterator, der seinen Status beibehält, erinnern Sie sich?). Der folgende Code funktioniert mit beiden Versionen einwandfrei: Python 2 und Python 3.
Hier ist ein Code:
import os
def files(path):
for file in os.listdir(path):
if os.path.isfile(os.path.join(path, file)):
yield file
for file in files("."):
print (file)
Die listdir()
Methode gibt die Liste der Einträge für das angegebene Verzeichnis zurück. Die Methode gibt os.path.isfile()
zurück, True
wenn der angegebene Eintrag eine Datei ist. Der yield
Operator beendet die Funktion, behält jedoch seinen aktuellen Status bei und gibt nur den Namen des als Datei erkannten Eintrags zurück. All dies ermöglicht es uns, die Generatorfunktion zu durchlaufen.
Das Zurückgeben einer Liste absoluter Dateipfade erfolgt nicht in Unterverzeichnissen
L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]
os.path.abspath(f)
wäre ein etwas billigerer Ersatz für os.path.join(os.getcwd(),f)
.
cwd = os.path.abspath('.')
und dann cwd
anstelle von '.'
und os.getcwd()
durchgehend verwenden würden, um viele redundante Systemaufrufe zu vermeiden.
import os
import os.path
def get_files(target_dir):
item_list = os.listdir(target_dir)
file_list = list()
for item in item_list:
item_dir = os.path.join(target_dir,item)
if os.path.isdir(item_dir):
file_list += get_files(item_dir)
else:
file_list.append(item_dir)
return file_list
Hier verwende ich eine rekursive Struktur.
Ein weiser Lehrer sagte mir einmal:
Wenn es mehrere etablierte Möglichkeiten gibt, etwas zu tun, ist keine davon für alle Fälle gut.
Ich werde daher eine Lösung für eine Teilmenge des Problems hinzufügen : Oft möchten wir nur prüfen, ob eine Datei mit einer Startzeichenfolge und einer Endzeichenfolge übereinstimmt, ohne in Unterverzeichnisse zu wechseln. Wir möchten daher eine Funktion, die eine Liste von Dateinamen zurückgibt, wie:
filenames = dir_filter('foo/baz', radical='radical', extension='.txt')
Wenn Sie zuerst zwei Funktionen deklarieren möchten, können Sie dies tun:
def file_filter(filename, radical='', extension=''):
"Check if a filename matches a radical and extension"
if not filename:
return False
filename = filename.strip()
return(filename.startswith(radical) and filename.endswith(extension))
def dir_filter(dirname='', radical='', extension=''):
"Filter filenames in directory according to radical and extension"
if not dirname:
dirname = '.'
return [filename for filename in os.listdir(dirname)
if file_filter(filename, radical, extension)]
Diese Lösung kann leicht mit regulären Ausdrücken verallgemeinert werden (und Sie möchten möglicherweise ein pattern
Argument hinzufügen , wenn Ihre Muster nicht immer am Anfang oder Ende des Dateinamens bleiben sollen).
Eine andere gut lesbare Variante für Python 3.4+ ist die Verwendung von pathlib.Path.glob:
from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]
Es ist einfach, genauer zu machen, z. B. nur in allen Unterverzeichnissen nach Python-Quelldateien zu suchen, die keine symbolischen Links sind:
[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]
Hier ist meine Allzweckfunktion dafür. Es gibt eine Liste von Dateipfaden anstelle von Dateinamen zurück, da ich dies als nützlicher empfand. Es gibt einige optionale Argumente, die es vielseitig machen. Zum Beispiel benutze ich es oft mit Argumenten wie pattern='*.txt'
oder subfolders=True
.
import os
import fnmatch
def list_paths(folder='.', pattern='*', case_sensitive=False, subfolders=False):
"""Return a list of the file paths matching the pattern in the specified
folder, optionally including files inside subfolders.
"""
match = fnmatch.fnmatchcase if case_sensitive else fnmatch.fnmatch
walked = os.walk(folder) if subfolders else [next(os.walk(folder))]
return [os.path.join(root, f)
for root, dirnames, filenames in walked
for f in filenames if match(f, pattern)]
Ich werde ein Beispiel für einen Liner bereitstellen, in dem Quellpfad und Dateityp als Eingabe angegeben werden können. Der Code gibt eine Liste von Dateinamen mit der Erweiterung csv zurück. Verwenden Sie . falls alle Dateien zurückgegeben werden müssen. Dadurch werden auch die Unterverzeichnisse rekursiv durchsucht.
[y for x in os.walk(sourcePath) for y in glob(os.path.join(x[0], '*.csv'))]
Ändern Sie die Dateierweiterungen und den Quellpfad nach Bedarf.
glob
einfach glob('**/*.csv', recursive=True)
. Keine Notwendigkeit, dies mit zu kombinieren, um os.walk()
zu rekursieren ( recursive
und **
werden seit Python 3.5 unterstützt).
Für python2: pip installiere rglob
import rglob
file_list=rglob.rglob("/home/base/dir/", "*")
print file_list
dircache ist "Veraltet seit Version 2.6: Das dircache-Modul wurde in Python 3.0 entfernt."
import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
if len(list[i]) != check:
temp.append(list[i-1])
check = len(list[i])
else:
i = i + 1
count = count - 1
print temp