Jawaban:
Anda bisa menggunakan glob
:
import glob, os
os.chdir("/mydir")
for file in glob.glob("*.txt"):
print(file)
atau hanya os.listdir
:
import os
for file in os.listdir("/mydir"):
if file.endswith(".txt"):
print(os.path.join("/mydir", file))
atau jika Anda ingin melintasi direktori, gunakan 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
daripada karena for files in f
karena apa yang ada dalam variabel adalah nama file tunggal. Yang lebih baik adalah mengubah f
to files
dan kemudian for for loop menjadi for file in files
.
file
bukan kata yang dilindungi undang-undang, hanya nama fungsi yang telah ditentukan, jadi sangat mungkin untuk menggunakannya sebagai nama variabel dalam kode Anda sendiri. Meskipun memang benar bahwa secara umum seseorang harus menghindari tabrakan seperti itu, file
adalah kasus khusus karena hampir tidak pernah ada kebutuhan untuk menggunakannya, sehingga sering dianggap pengecualian terhadap pedoman. Jika Anda tidak ingin melakukan itu, PEP8 merekomendasikan menambahkan satu garis bawah untuk nama-nama tersebut, yaitu file_
, yang harus Anda setujui masih dapat dibaca.
Gunakan glob .
>>> import glob
>>> glob.glob('./*.txt')
['./outline.txt', './pip-log.txt', './test.txt', './testingvim.txt']
glob
tidak dapat menemukan file secara rekursif jika python Anda di bawah 3.5. informasi lebih lanjut
Sesuatu seperti itu harus melakukan pekerjaannya
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith('.txt'):
print file
root, dirs, files
bukan r, d, f
. Jauh lebih mudah dibaca.
Sesuatu seperti ini akan bekerja:
>>> 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
pada setiap elemen text_files
. Bisa jadi sesuatu seperti text_files = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.txt')]
.
Anda cukup menggunakan pathlib
s 1 :glob
import pathlib
list(pathlib.Path('your_directory').glob('*.txt'))
atau dalam satu lingkaran:
for txt_file in pathlib.Path('your_directory').glob('*.txt'):
# do something with "txt_file"
Jika Anda menginginkannya bersifat rekursif, Anda dapat menggunakannya .glob('**/*.txt)
1 The pathlib
Modul termasuk dalam perpustakaan standar di python 3.4. Tetapi Anda dapat menginstal port-kembali modul itu bahkan pada versi Python yang lebih lama (yaitu menggunakan conda
atau pip
): pathlib
dan pathlib2
.
**/*.txt
tidak didukung oleh versi python yang lebih lama. Jadi saya memecahkan masalah ini dengan: foundfiles= subprocess.check_output("ls **/*.txt", shell=True)
for foundfile in foundfiles.splitlines():
print foundfile
pathlib
bisa dilakukan dan saya sudah memasukkan persyaratan versi Python. :) Tetapi jika pendekatan Anda belum diposting mengapa tidak menambahkannya sebagai jawaban lain?
rglob
jika Anda ingin mencari item secara rekursif. Misalnya.rglob('*.txt')
import os
path = 'mypath/path'
files = os.listdir(path)
files_txt = [i for i in files if i.endswith('.txt')]
Saya suka 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)
Atau dengan generator:
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)
Berikut ini lebih banyak versi yang sama yang menghasilkan hasil yang sedikit berbeda:
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()
adalah fungsi pembantu dalam glob
modul yang tidak tercantum dalam dokumentasi Python. Ada beberapa komentar inline yang menjelaskan apa yang dilakukannya di file sumber, lihat .../Lib/glob.py
.
glob.glob1()
tidak umum tetapi tersedia di Python 2.4-2.7; 3.0-3.2; pypy; jython github.com/zed/test_glob1
glob
modul.
path.py adalah alternatif lain: 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')
melalui setiap subfolder
list(p.glob('**/*.py'))
Metode cepat menggunakan os.scandir dalam fungsi rekursif. Mencari semua file dengan ekstensi yang ditentukan dalam folder dan sub-folder.
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)
Jika Anda mencari di direktori yang berisi 10.000 file, menambahkan ke daftar menjadi tidak efisien. 'Menghasilkan' hasilnya adalah solusi yang lebih baik. Saya juga menyertakan fungsi untuk mengkonversi output ke Pandframe 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 memiliki semua alat untuk melakukan ini:
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)))
Untuk mendapatkan semua nama file '.txt' di dalam folder 'dataPath' sebagai daftar dengan cara 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
Coba ini, ini akan menemukan semua file Anda secara rekursif:
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)
**
. Hanya tersedia dalam python 3. Yang tidak saya sukai adalah chdir
bagiannya. Tidak perlu untuk itu.
filepath = os.path.join('wallpaper')
dan kemudian menggunakannya sebagai glob.glob(filepath+"**/*.psd", recursive = True)
, yang akan menghasilkan hasil yang sama.
Saya melakukan tes (Python 3.6.4, W7x64) untuk melihat solusi mana yang tercepat untuk satu folder, tanpa subdirektori, untuk mendapatkan daftar path file lengkap untuk file dengan ekstensi spesifik.
Singkatnya, untuk tugas ini os.listdir()
adalah yang tercepat dan 1,7x lebih cepat dari yang terbaik berikutnya: os.walk()
(dengan istirahat!), 2,7x secepat pathlib
, 3,2x lebih cepat dari os.scandir()
dan 3,3x lebih cepat daripada glob
.
Harap diingat, bahwa hasil itu akan berubah ketika Anda membutuhkan hasil rekursif. Jika Anda menyalin / menempel satu metode di bawah ini, harap tambahkan .lower () jika tidak .EXT tidak akan ditemukan saat mencari .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))
Hasil:
# Python 3.6.4
0.431
0.515
0.161
0.548
0.537
0.274
Kode ini membuat hidup saya lebih sederhana.
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)
Gunakan 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
Untuk mendapatkan larik nama file ".txt" dari folder bernama "data" di direktori yang sama, saya biasanya menggunakan baris kode sederhana ini:
import os
fileNames = [fileName for fileName in os.listdir("data") if fileName.endswith(".txt")]
Saya menyarankan Anda untuk menggunakan fnmatch dan metode atas. Dengan cara ini Anda dapat menemukan salah satu dari yang berikut:
.
import fnmatch
import os
for file in os.listdir("/Users/Johnny/Desktop/MyTXTfolder"):
if fnmatch.fnmatch(file.upper(), '*.TXT'):
print(file)
Solusi fungsional dengan sub-direktori:
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"))))
Jika folder tersebut berisi banyak file atau memori merupakan kendala, pertimbangkan untuk menggunakan generator:
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
Opsi A: Iterate
for f in yield_files_with_extensions('.', '.txt'):
print(f)
Opsi B: Dapatkan semua
files = [f for f in yield_files_with_extensions('.', '.txt')]
Solusi copy-pastable mirip dengan 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
gunakan modul Python OS untuk menemukan file dengan ekstensi spesifik.
contoh sederhana ada di sini:
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
Banyak pengguna menjawab dengan os.walk
jawaban, yang mencakup semua file tetapi juga semua direktori dan subdirektori dan file mereka.
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)
Atau untuk yang tidak memerlukan generator:
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)
Jika Anda akan menggunakan kecocokan untuk sesuatu yang lain, Anda mungkin ingin menjadikannya daftar daripada ekspresi generator:
matches = [f for f in dirfiles if f.endswith(ext)]
Metode sederhana dengan menggunakan 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")
Padahal ini bisa dibuat lebih umum.