Antworten:
Sie können verwenden glob
:
import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
print(file)
oder einfach os.listdir
:
import os
for file in os.listdir("/mydir"):
if file.endswith(".txt"):
print(os.path.join("/mydir", file))
oder wenn Sie das Verzeichnis durchlaufen möchten, verwenden Sie os.walk
:
import os
for root, dirs, files in os.walk("/mydir"):
for file in files:
if file.endswith(".txt"):
print(os.path.join(root, file))
for file in f
als für, for files in f
da die Variable einen einzelnen Dateinamen enthält. Noch besser wäre es, die f
to- files
und dann die for-Schleifen zu ändern for file in files
.
file
ist kein reserviertes Wort, sondern nur der Name einer vordefinierten Funktion. Daher ist es durchaus möglich, es als Variablennamen in Ihrem eigenen Code zu verwenden. Obwohl es stimmt, dass solche Kollisionen im Allgemeinen vermieden werden sollten, file
ist dies ein Sonderfall, da es kaum erforderlich ist, sie zu verwenden, weshalb häufig eine Ausnahme von der Richtlinie in Betracht gezogen wird. Wenn Sie dies nicht möchten, empfiehlt PEP8, solchen Namen einen einzelnen Unterstrich hinzuzufügen, dh file_
, dem Sie zustimmen müssen, dass er immer noch gut lesbar ist.
Verwenden Sie glob .
>>> import glob
>>> glob.glob('./*.txt')
['./outline.txt', './pip-log.txt', './test.txt', './testingvim.txt']
glob
Dateien nicht rekursiv gefunden werden können, wenn Ihr Python unter 3.5 liegt. Weitere Informationen
So etwas sollte den Job machen
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.txt'):
print file
root, dirs, files
anstelle von r, d, f
. Viel besser lesbar.
So etwas wird funktionieren:
>>> import os
>>> path = '/usr/share/cups/charmaps'
>>> text_files = [f for f in os.listdir(path) if f.endswith('.txt')]
>>> text_files
['euc-cn.txt', 'euc-jp.txt', 'euc-kr.txt', 'euc-tw.txt', ... 'windows-950.txt']
os.path.join
für jedes Element von verwenden text_files
. Es könnte so etwas sein text_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.txt')]
.
Sie können einfach pathlib
s 1 verwenden :glob
import pathlib
list(pathlib.Path('your_directory').glob('*.txt'))
oder in einer Schleife:
for txt_file in pathlib.Path('your_directory').glob('*.txt'):
# do something with "txt_file"
Wenn Sie es rekursiv wollen, können Sie verwenden .glob('**/*.txt)
1 Das pathlib
Modul wurde in die Standardbibliothek in Python 3.4 aufgenommen. Sie können Back-Ports dieses Moduls jedoch auch auf älteren Python-Versionen installieren (z. B. mit conda
oder pip
): pathlib
und pathlib2
.
**/*.txt
wird von älteren Python-Versionen nicht unterstützt. Also habe ich dies gelöst mit: foundfiles= subprocess.check_output("ls **/*.txt", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
pathlib
tun ist, und ich habe bereits die Python-Versionsanforderungen aufgenommen. :) Aber wenn Ihr Ansatz noch nicht veröffentlicht wurde, fügen Sie ihn doch einfach als weitere Antwort hinzu.
rglob
wenn Sie rekursiv nach Elementen suchen möchten. ZB.rglob('*.txt')
import os
path = 'mypath/path'
files = os.listdir(path)
files_txt = [i for i in files if i.endswith('.txt')]
Ich mag os.walk () :
import os
for root, dirs, files in os.walk(dir):
for f in files:
if os.path.splitext(f)[1] == '.txt':
fullpath = os.path.join(root, f)
print(fullpath)
Oder mit Generatoren:
import os
fileiter = (os.path.join(root, f)
for root, _, files in os.walk(dir)
for f in files)
txtfileiter = (f for f in fileiter if os.path.splitext(f)[1] == '.txt')
for txt in txtfileiter:
print(txt)
Hier sind weitere Versionen derselben, die leicht unterschiedliche Ergebnisse liefern:
import glob
for f in glob.iglob("/mydir/*/*.txt"): # generator, search immediate subdirectories
print f
print glob.glob1("/mydir", "*.tx?") # literal_directory, basename_pattern
import fnmatch, os
print fnmatch.filter(os.listdir("/mydir"), "*.tx?") # include dot-files
glob1()
es eine Hilfsfunktion im glob
Modul, die nicht in der Python-Dokumentation aufgeführt ist. Es gibt einige Inline-Kommentare, die beschreiben, was es in der Quelldatei tut, siehe .../Lib/glob.py
.
glob.glob1()
ist nicht öffentlich, aber verfügbar für Python 2.4-2.7; 3.0-3.2; Pypy; jython github.com/zed/test_glob1
glob
Modul extrahiert werden.
path.py ist eine weitere Alternative: https://github.com/jaraco/path.py
from path import path
p = path('/path/to/the/directory')
for f in p.files(pattern='*.txt'):
print f
for f in p.walk(pattern='*.txt')
go durch alle Unterordner
list(p.glob('**/*.py'))
Schnelle Methode mit os.scandir in einer rekursiven Funktion. Sucht nach allen Dateien mit einer angegebenen Erweiterung in Ordnern und Unterordnern.
import os
def findFilesInFolder(path, pathList, extension, subFolders = True):
""" Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)
path: Base directory to find files
pathList: A list that stores all paths
extension: File extension to find
subFolders: Bool. If True, find files in all subfolders under path. If False, only searches files in the specified folder
"""
try: # Trapping a OSError: File permissions problem I believe
for entry in os.scandir(path):
if entry.is_file() and entry.path.endswith(extension):
pathList.append(entry.path)
elif entry.is_dir() and subFolders: # if its a directory, then repeat process as a nested function
pathList = findFilesInFolder(entry.path, pathList, extension, subFolders)
except OSError:
print('Cannot access ' + path +'. Probably a permissions error')
return pathList
dir_name = r'J:\myDirectory'
extension = ".txt"
pathList = []
pathList = findFilesInFolder(dir_name, pathList, extension, True)
Wenn Sie über Verzeichnisse suchen, die 10.000 Dateien enthalten, wird das Anhängen an eine Liste ineffizient. Das Ergebnis zu erzielen ist eine bessere Lösung. Ich habe auch eine Funktion zum Konvertieren der Ausgabe in einen Pandas-Datenrahmen hinzugefügt.
import os
import re
import pandas as pd
import numpy as np
def findFilesInFolderYield(path, extension, containsTxt='', subFolders = True, excludeText = ''):
""" Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)
path: Base directory to find files
extension: File extension to find. e.g. 'txt'. Regular expression. Or 'ls\d' to match ls1, ls2, ls3 etc
containsTxt: List of Strings, only finds file if it contains this text. Ignore if '' (or blank)
subFolders: Bool. If True, find files in all subfolders under path. If False, only searches files in the specified folder
excludeText: Text string. Ignore if ''. Will exclude if text string is in path.
"""
if type(containsTxt) == str: # if a string and not in a list
containsTxt = [containsTxt]
myregexobj = re.compile('\.' + extension + '$') # Makes sure the file extension is at the end and is preceded by a .
try: # Trapping a OSError or FileNotFoundError: File permissions problem I believe
for entry in os.scandir(path):
if entry.is_file() and myregexobj.search(entry.path): #
bools = [True for txt in containsTxt if txt in entry.path and (excludeText == '' or excludeText not in entry.path)]
if len(bools)== len(containsTxt):
yield entry.stat().st_size, entry.stat().st_atime_ns, entry.stat().st_mtime_ns, entry.stat().st_ctime_ns, entry.path
elif entry.is_dir() and subFolders: # if its a directory, then repeat process as a nested function
yield from findFilesInFolderYield(entry.path, extension, containsTxt, subFolders)
except OSError as ose:
print('Cannot access ' + path +'. Probably a permissions error ', ose)
except FileNotFoundError as fnf:
print(path +' not found ', fnf)
def findFilesInFolderYieldandGetDf(path, extension, containsTxt, subFolders = True, excludeText = ''):
""" Converts returned data from findFilesInFolderYield and creates and Pandas Dataframe.
Recursive function to find all files of an extension type in a folder (and optionally in all subfolders too)
path: Base directory to find files
extension: File extension to find. e.g. 'txt'. Regular expression. Or 'ls\d' to match ls1, ls2, ls3 etc
containsTxt: List of Strings, only finds file if it contains this text. Ignore if '' (or blank)
subFolders: Bool. If True, find files in all subfolders under path. If False, only searches files in the specified folder
excludeText: Text string. Ignore if ''. Will exclude if text string is in path.
"""
fileSizes, accessTimes, modificationTimes, creationTimes , paths = zip(*findFilesInFolderYield(path, extension, containsTxt, subFolders))
df = pd.DataFrame({
'FLS_File_Size':fileSizes,
'FLS_File_Access_Date':accessTimes,
'FLS_File_Modification_Date':np.array(modificationTimes).astype('timedelta64[ns]'),
'FLS_File_Creation_Date':creationTimes,
'FLS_File_PathName':paths,
})
df['FLS_File_Modification_Date'] = pd.to_datetime(df['FLS_File_Modification_Date'],infer_datetime_format=True)
df['FLS_File_Creation_Date'] = pd.to_datetime(df['FLS_File_Creation_Date'],infer_datetime_format=True)
df['FLS_File_Access_Date'] = pd.to_datetime(df['FLS_File_Access_Date'],infer_datetime_format=True)
return df
ext = 'txt' # regular expression
containsTxt=[]
path = 'C:\myFolder'
df = findFilesInFolderYieldandGetDf(path, ext, containsTxt, subFolders = True)
Python verfügt über alle Tools, um dies zu tun:
import os
the_dir = 'the_dir_that_want_to_search_in'
all_txt_files = filter(lambda x: x.endswith('.txt'), os.listdir(the_dir))
all_txt_files = list(filter(lambda x: x.endswith('.txt'), os.listdir(the_dir)))
Versuchen Sie dies, um alle Ihre Dateien rekursiv zu finden:
import glob, os
os.chdir("H:\\wallpaper")# use whatever directory you want
#double\\ no single \
for file in glob.glob("**/*.txt", recursive = True):
print(file)
**
. Nur in Python 3 verfügbar. Was mir nicht gefällt, ist der chdir
Teil. Keinen Bedarf.
filepath = os.path.join('wallpaper')
Nun , Sie könnten die OS-Bibliothek verwenden, um den Pfad zu verbinden, z. B., und ihn dann als verwenden glob.glob(filepath+"**/*.psd", recursive = True)
, was das gleiche Ergebnis liefern würde.
Ich habe einen Test (Python 3.6.4, W7x64) durchgeführt, um festzustellen, welche Lösung für einen Ordner ohne Unterverzeichnisse am schnellsten ist, um eine Liste der vollständigen Dateipfade für Dateien mit einer bestimmten Erweiterung zu erhalten.
Um es kurz zu machen, diese Aufgabe os.listdir()
ist die schnellste und 1,7-mal so schnell wie die nächstbeste: os.walk()
(mit einer Pause!), 2,7-mal so schnell wie pathlib
, 3,2-mal schneller als os.scandir()
und 3,3-mal schneller als glob
.
Bitte beachten Sie, dass sich diese Ergebnisse ändern, wenn Sie rekursive Ergebnisse benötigen. Wenn Sie eine der folgenden Methoden kopieren / einfügen, fügen Sie bitte eine .lower () hinzu, da sonst .EXT bei der Suche nach .ext nicht gefunden wird.
import os
import pathlib
import timeit
import glob
def a():
path = pathlib.Path().cwd()
list_sqlite_files = [str(f) for f in path.glob("*.sqlite")]
def b():
path = os.getcwd()
list_sqlite_files = [f.path for f in os.scandir(path) if os.path.splitext(f)[1] == ".sqlite"]
def c():
path = os.getcwd()
list_sqlite_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith(".sqlite")]
def d():
path = os.getcwd()
os.chdir(path)
list_sqlite_files = [os.path.join(path, f) for f in glob.glob("*.sqlite")]
def e():
path = os.getcwd()
list_sqlite_files = [os.path.join(path, f) for f in glob.glob1(str(path), "*.sqlite")]
def f():
path = os.getcwd()
list_sqlite_files = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(".sqlite"):
list_sqlite_files.append( os.path.join(root, file) )
break
print(timeit.timeit(a, number=1000))
print(timeit.timeit(b, number=1000))
print(timeit.timeit(c, number=1000))
print(timeit.timeit(d, number=1000))
print(timeit.timeit(e, number=1000))
print(timeit.timeit(f, number=1000))
Ergebnisse:
# Python 3.6.4
0.431
0.515
0.161
0.548
0.537
0.274
Dieser Code macht mein Leben einfacher.
import os
fnames = ([file for root, dirs, files in os.walk(dir)
for file in files
if file.endswith('.txt') #or file.endswith('.png') or file.endswith('.pdf')
])
for fname in fnames: print(fname)
Verwenden Sie fnmatch: https://docs.python.org/2/library/fnmatch.html
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print file
Um ein Array von ".txt" -Dateinamen aus einem Ordner namens "data" im selben Verzeichnis abzurufen, verwende ich normalerweise diese einfache Codezeile:
import os
fileNames = [fileName for fileName in os.listdir("data") if fileName.endswith(".txt")]
Ich empfehle Ihnen, fnmatch und die obere Methode zu verwenden. Auf diese Weise können Sie Folgendes finden:
.
import fnmatch
import os
for file in os.listdir("/Users/Johnny/Desktop/MyTXTfolder"):
if fnmatch.fnmatch(file.upper(), '*.TXT'):
print(file)
Funktionslösung mit Unterverzeichnissen:
from fnmatch import filter
from functools import partial
from itertools import chain
from os import path, walk
print(*chain(*(map(partial(path.join, root), filter(filenames, "*.txt")) for root, _, filenames in walk("mydir"))))
Wenn der Ordner viele Dateien enthält oder der Speicher eine Einschränkung darstellt, sollten Sie Generatoren verwenden:
def yield_files_with_extensions(folder_path, file_extension):
for _, _, files in os.walk(folder_path):
for file in files:
if file.endswith(file_extension):
yield file
Option A: Iterieren
for f in yield_files_with_extensions('.', '.txt'):
print(f)
Option B: Holen Sie sich alle
files = [f for f in yield_files_with_extensions('.', '.txt')]
Eine kopierbare Lösung ähnlich der von Ghostdog:
def get_all_filepaths(root_path, ext):
"""
Search all files which have a given extension within root_path.
This ignores the case of the extension and searches subdirectories, too.
Parameters
----------
root_path : str
ext : str
Returns
-------
list of str
Examples
--------
>>> get_all_filepaths('/run', '.lock')
['/run/unattended-upgrades.lock',
'/run/mlocate.daily.lock',
'/run/xtables.lock',
'/run/mysqld/mysqld.sock.lock',
'/run/postgresql/.s.PGSQL.5432.lock',
'/run/network/.ifstate.lock',
'/run/lock/asound.state.lock']
"""
import os
all_files = []
for root, dirs, files in os.walk(root_path):
for filename in files:
if filename.lower().endswith(ext):
all_files.append(os.path.join(root, filename))
return all_files
Verwenden Sie das Python OS- Modul, um Dateien mit einer bestimmten Erweiterung zu finden.
Das einfache Beispiel ist hier:
import os
# This is the path where you want to search
path = r'd:'
# this is extension you want to detect
extension = '.txt' # this can be : .jpg .png .xls .log .....
for root, dirs_list, files_list in os.walk(path):
for file_name in files_list:
if os.path.splitext(file_name)[-1] == extension:
file_name_path = os.path.join(root, file_name)
print file_name
print file_name_path # This is the full path of the filter file
Viele Benutzer haben mit os.walk
Antworten geantwortet , die alle Dateien, aber auch alle Verzeichnisse und Unterverzeichnisse sowie deren Dateien enthalten.
import os
def files_in_dir(path, extension=''):
"""
Generator: yields all of the files in <path> ending with
<extension>
\param path Absolute or relative path to inspect,
\param extension [optional] Only yield files matching this,
\yield [filenames]
"""
for _, dirs, files in os.walk(path):
dirs[:] = [] # do not recurse directories.
yield from [f for f in files if f.endswith(extension)]
# Example: print all the .py files in './python'
for filename in files_in_dir('./python', '*.py'):
print("-", filename)
Oder für einen Einzelfall, bei dem Sie keinen Generator benötigen:
path, ext = "./python", ext = ".py"
for _, _, dirfiles in os.walk(path):
matches = (f for f in dirfiles if f.endswith(ext))
break
for filename in matches:
print("-", filename)
Wenn Sie Übereinstimmungen für etwas anderes verwenden möchten, möchten Sie möglicherweise eine Liste anstelle eines Generatorausdrucks erstellen:
matches = [f for f in dirfiles if f.endswith(ext)]
Eine einfache Methode mit for
loop:
import os
dir = ["e","x","e"]
p = os.listdir('E:') #path
for n in range(len(p)):
name = p[n]
myfile = [name[-3],name[-2],name[-1]] #for .txt
if myfile == dir :
print(name)
else:
print("nops")
Dies kann jedoch verallgemeinert werden.