Réponses:
Vous pouvez utiliser glob
:
import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
print(file)
ou simplement os.listdir
:
import os
for file in os.listdir("/mydir"):
if file.endswith(".txt"):
print(os.path.join("/mydir", file))
ou si vous souhaitez parcourir le répertoire, utilisez 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
que pour for files in f
puisque ce qui est dans la variable est un nom de fichier unique. Encore mieux serait de changer les boucles f
to files
, puis les boucles for pourraient devenir for file in files
.
file
n'est pas un mot réservé, juste le nom d'une fonction prédéfinie, il est donc tout à fait possible de l'utiliser comme nom de variable dans votre propre code. Bien qu'il soit vrai qu'en général, il faut éviter de telles collisions, file
c'est un cas particulier car il n'y a presque jamais besoin de l'utiliser, il est donc souvent considéré comme une exception à la directive. Si vous ne voulez pas faire cela, PEP8 recommande d'ajouter un seul trait de soulignement à ces noms, c'est file_
-à- dire que vous devez accepter est encore tout à fait lisible.
Utilisez glob .
>>> import glob
>>> glob.glob('./*.txt')
['./outline.txt', './pip-log.txt', './test.txt', './testingvim.txt']
glob
vous ne pouvez pas trouver de fichiers récursivement si votre python est inférieur à 3.5. plus d'informations
Quelque chose comme ça devrait faire le travail
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.txt'):
print file
root, dirs, files
au lieu de r, d, f
. Beaucoup plus lisible.
Quelque chose comme ça fonctionnera:
>>> 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
sur chaque élément de text_files
. Ça pourrait être quelque chose comme ça text_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.txt')]
.
Vous pouvez simplement utiliser pathlib
s 1 :glob
import pathlib
list(pathlib.Path('your_directory').glob('*.txt'))
ou en boucle:
for txt_file in pathlib.Path('your_directory').glob('*.txt'):
# do something with "txt_file"
Si vous le souhaitez récursif, vous pouvez utiliser .glob('**/*.txt)
1 Le pathlib
module a été inclus dans la bibliothèque standard de python 3.4. Mais vous pouvez installer les ports arrière de ce module même sur les anciennes versions de Python (c'est-à-dire en utilisant conda
ou pip
): pathlib
et pathlib2
.
**/*.txt
n'est pas pris en charge par les anciennes versions de python. J'ai donc résolu ce problème avec: foundfiles= subprocess.check_output("ls **/*.txt", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
pathlib
peut faire et j'ai déjà inclus les exigences de la version Python. :) Mais si votre approche n'a pas encore été publiée, pourquoi ne pas simplement l'ajouter comme autre réponse?
rglob
si vous souhaitez rechercher des éléments de manière récursive. Par exemple.rglob('*.txt')
import os
path = 'mypath/path'
files = os.listdir(path)
files_txt = [i for i in files if i.endswith('.txt')]
J'aime 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)
Ou avec des générateurs:
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)
Voici d'autres versions du même qui produisent des résultats légèrement différents:
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()
est une fonction d'aide dans le glob
module qui n'est pas répertoriée dans la documentation Python. Il y a des commentaires en ligne décrivant ce qu'il fait dans le fichier source, voir .../Lib/glob.py
.
glob.glob1()
n'est pas public mais il est disponible sur Python 2.4-2.7; 3.0-3.2; pypy; jython github.com/zed/test_glob1
glob
module.
path.py est une autre 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 through every subfolders
list(p.glob('**/*.py'))
Méthode rapide utilisant os.scandir dans une fonction récursive. Recherche tous les fichiers avec une extension spécifiée dans le dossier et les sous-dossiers.
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)
Si vous recherchez dans des répertoires contenant 10 000 fichiers, l'ajout à une liste devient inefficace. «Céder» les résultats est une meilleure solution. J'ai également inclus une fonction pour convertir la sortie en un Pandas Dataframe.
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 a tous les outils pour le faire:
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)))
Pour obtenir tous les noms de fichiers '.txt' dans le dossier 'dataPath' sous forme de liste de manière Pythonic:
from os import listdir
from os.path import isfile, join
path = "/dataPath/"
onlyTxtFiles = [f for f in listdir(path) if isfile(join(path, f)) and f.endswith(".txt")]
print onlyTxtFiles
Essayez ceci, cela trouvera tous vos fichiers récursivement:
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)
**
. Uniquement disponible en python 3. Ce que je n'aime pas, c'est la chdir
partie. Pas besoin de çà.
filepath = os.path.join('wallpaper')
puis l'utiliser comme glob.glob(filepath+"**/*.psd", recursive = True)
, ce qui donnerait le même résultat.
J'ai fait un test (Python 3.6.4, W7x64) pour voir quelle solution est la plus rapide pour un dossier, pas de sous-répertoires, pour obtenir une liste de chemins de fichiers complets pour les fichiers avec une extension spécifique.
Pour faire court, cette tâche os.listdir()
est la plus rapide et 1,7 fois plus rapide que la suivante: os.walk()
(avec une pause!), 2,7 fois plus rapide, 3,2 fois plus rapide pathlib
que os.scandir()
et 3,3 fois plus rapide que glob
.
N'oubliez pas que ces résultats changeront lorsque vous aurez besoin de résultats récursifs. Si vous copiez / collez une méthode ci-dessous, veuillez ajouter un .lower () sinon .EXT ne sera pas trouvé lors de la recherche de .ext.
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))
Résultats:
# Python 3.6.4
0.431
0.515
0.161
0.548
0.537
0.274
Ce code me simplifie la vie.
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)
Utilisez 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
Pour obtenir un tableau de noms de fichiers ".txt" à partir d'un dossier appelé "data" dans le même répertoire, j'utilise généralement cette simple ligne de code:
import os
fileNames = [fileName for fileName in os.listdir("data") if fileName.endswith(".txt")]
Je vous suggère d'utiliser fnmatch et la méthode supérieure. De cette façon, vous pouvez trouver l'un des éléments suivants:
.
import fnmatch
import os
for file in os.listdir("/Users/Johnny/Desktop/MyTXTfolder"):
if fnmatch.fnmatch(file.upper(), '*.TXT'):
print(file)
Solution fonctionnelle avec sous-répertoires:
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"))))
Dans le cas où le dossier contient beaucoup de fichiers ou si la mémoire est une contrainte, pensez à utiliser des générateurs:
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: répéter
for f in yield_files_with_extensions('.', '.txt'):
print(f)
Option B: Obtenez tout
files = [f for f in yield_files_with_extensions('.', '.txt')]
Une solution copiable-collable similaire à celle de 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
utilisez le module Python OS pour rechercher des fichiers avec une extension spécifique.
l'exemple simple est ici:
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
De nombreux utilisateurs ont répondu avec des os.walk
réponses, qui incluent tous les fichiers mais aussi tous les répertoires et sous-répertoires et leurs fichiers.
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)
Ou pour un seul où vous n'avez pas besoin d'un générateur:
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)
Si vous allez utiliser des correspondances pour autre chose, vous pouvez en faire une liste plutôt qu'une expression de générateur:
matches = [f for f in dirfiles if f.endswith(ext)]
Une méthode simple en utilisant la for
boucle:
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")
Bien que cela puisse être généralisé.