Yanıtlar:
Şunları kullanabilirsiniz glob
:
import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
print(file)
ya da basitçe os.listdir
:
import os
for file in os.listdir("/mydir"):
if file.endswith(".txt"):
print(os.path.join("/mydir", file))
veya dizinde geçiş yapmak istiyorsanız, şunu kullanın 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
olduğu için yazmak daha uygun olurdu for files in f
. Daha da iyisi değiştirmek olacaktır f
için files
daha sonra döngüler için haline gelebilir ve for file in files
.
file
ayrılmış bir sözcük değil, yalnızca önceden tanımlanmış bir işlevin adıdır, bu nedenle bunu kendi kodunuzda değişken adı olarak kullanmak oldukça mümkündür. Genellikle böyle çarpışmalardan kaçınması gerektiği doğru olsa da, file
özel bir durumdur, çünkü onu kullanmaya hiç gerek yoktur, bu nedenle genellikle kılavuzun bir istisnası olarak kabul edilir. Bunu yapmak istemiyorsanız, PEP8 bu tür isimlere tek bir alt çizgi eklemenizi önerir, yani file_
, hala oldukça okunabilir olduğunu kabul etmeniz gerekir.
Glob kullanın .
>>> import glob
>>> glob.glob('./*.txt')
['./outline.txt', './pip-log.txt', './test.txt', './testingvim.txt']
glob
dosyaları tekrar tekrar bulamayacağınıza dikkat edin . daha fazla bilgi
Böyle bir şey işi yapmalı
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.txt'):
print file
root, dirs, files
yerine r, d, f
. Çok daha okunabilir.
Böyle bir şey işe yarayacak:
>>> 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
Öğesinin her öğesinde kullanabilirsiniz text_files
. Böyle bir şey olabilir text_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.txt')]
.
Sadece pathlib
s 1'i kullanabilirsiniz :glob
import pathlib
list(pathlib.Path('your_directory').glob('*.txt'))
veya bir döngü içinde:
for txt_file in pathlib.Path('your_directory').glob('*.txt'):
# do something with "txt_file"
Özyinelemeyi istiyorsanız .glob('**/*.txt)
1pathlib
modül piton 3.4 standart kütüphanesinde yer aldı. Ancak bu modülün arka bağlantı noktalarını eski Python sürümlerine bile (yani conda
veya kullanarak pip
) yükleyebilirsiniz : pathlib
ve pathlib2
.
**/*.txt
eski python sürümleri tarafından desteklenmez.Bu yüzden bunu çözdüm: foundfiles= subprocess.check_output("ls **/*.txt", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
pathlib
yapabileceğimi gösteriyordu ve ben zaten Python sürüm gereksinimlerini ekledim . :) Ama eğer yaklaşımınız henüz gönderilmemişse neden sadece başka bir cevap olarak eklemiyorsunuz?
rglob
Öğeleri özyinelemeli olarak aramak istiyorsanız da kullanabileceğinizi unutmayın . Örn..rglob('*.txt')
import os
path = 'mypath/path'
files = os.listdir(path)
files_txt = [i for i in files if i.endswith('.txt')]
Ben os.walk () gibi :
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)
Veya jeneratörlerle:
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)
İşte biraz farklı sonuçlar üreten aynı sürümler:
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()
yardımcı bir işlevdir glob
. Kaynak dosyada ne yaptığını açıklayan bazı satır içi yorumlar var, bakın .../Lib/glob.py
.
glob.glob1()
herkese açık değil ancak Python 2.4-2.7; 3.0-3.2; PYPY; jython github.com/zed/test_glob1
glob
modülden kolayca çıkarılabilir gibi görünüyor .
path.py başka bir alternatiftir: 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')
her alt klasörler aracılığıyla gitmek
list(p.glob('**/*.py'))
Özyinelemeli bir işlevde os.scandir kullanarak hızlı yöntem. Klasör ve alt klasörlerde belirtilen uzantıya sahip tüm dosyaları arar.
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)
10.000 sn dosya içeren dizinlerde arama yapıyorsanız, listeye ekleme yapmak verimsiz hale gelir. Sonuçları 'elde etmek' daha iyi bir çözümdür. Ayrıca çıktı bir Panda veri çerçevesine dönüştürmek için bir işlev ekledik.
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 bunu yapmak için tüm araçlara sahiptir:
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)))
Bunu deneyin, tüm dosyalarınızı tekrar tekrar bulacaktır:
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)
**
. Sadece python 3'te mevcut. Sevmediğim chdir
kısım. Buna gerek yok.
filepath = os.path.join('wallpaper')
kullanabilirsiniz , ve daha sonra glob.glob(filepath+"**/*.psd", recursive = True)
aynı sonucu verecek şekilde olarak kullanabilirsiniz.
Belirli bir uzantıya sahip dosyalar için tam dosya yollarının bir listesini almak için bir klasör, alt dizinler için en hızlı olan çözümün hangisi olduğunu görmek için bir test yaptım (Python 3.6.4, W7x64).
Kısacası, bu görev os.listdir()
için en hızlı ve bir sonraki en iyi kadar 1,7 kat daha hızlı: os.walk()
(ara ile!), 2,7 kat daha hızlı, 3,2 kat daha hızlı ve 3,3 pathlib
kat daha os.scandir()
hızlı glob
.
Yinelenen sonuçlara ihtiyacınız olduğunda bu sonuçların değişeceğini lütfen unutmayın. Aşağıdaki yöntemlerden birini kopyalayıp yapıştırırsanız, lütfen bir .lower () ekleyin, aksi takdirde .ext aranırken .EXT bulunamaz.
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))
Sonuçlar:
# Python 3.6.4
0.431
0.515
0.161
0.548
0.537
0.274
Bu kod hayatımı kolaylaştırıyor.
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)
Fnmatch kullanın: https://docs.python.org/2/library/fnmatch.html
import fnmatch
import os
for file in os.listdir('.'):
if fnmatch.fnmatch(file, '*.txt'):
print file
Aynı dizinde "veri" adlı bir klasörden bir dizi ".txt" dosya adları almak için genellikle bu basit kod satırını kullanın:
import os
fileNames = [fileName for fileName in os.listdir("data") if fileName.endswith(".txt")]
Fnmatch ve üst yöntemi kullanmanızı öneririm . Bu şekilde aşağıdakilerden herhangi birini bulabilirsiniz:
.
import fnmatch
import os
for file in os.listdir("/Users/Johnny/Desktop/MyTXTfolder"):
if fnmatch.fnmatch(file.upper(), '*.TXT'):
print(file)
Alt dizinlerle fonksiyonel çözüm:
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"))))
Klasörün çok fazla dosya içermesi veya bellek bir kısıtlama olması durumunda, jeneratörleri kullanmayı düşünün:
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
Seçenek A: Yineleme
for f in yield_files_with_extensions('.', '.txt'):
print(f)
Seçenek B: Tümünü al
files = [f for f in yield_files_with_extensions('.', '.txt')]
Hayaletkine benzer kopyalanabilir bir çözüm:
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
Python OS kullanbelirli bir uzantıya sahip dosyaları bulmak modülünü kullanın.
basit örnek burada:
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
Birçok kullanıcı os.walk
, tüm dosyaları, aynı zamanda tüm dizinleri ve alt dizinleri ve dosyalarını içeren cevapları yanıtladı .
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)
Veya bir jeneratöre ihtiyacınız olmayan bir sefer için:
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)
Eşleşmeleri başka bir şey için kullanacaksanız, bunu bir jeneratör ifadesi yerine bir liste yapmak isteyebilirsiniz:
matches = [f for f in dirfiles if f.endswith(ext)]
for
Döngü kullanarak basit bir yöntem :
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")
Bu daha genelleştirilebilir olsa da.