Làm cách nào tôi có thể liệt kê tất cả các tệp của một thư mục trong Python và thêm chúng vào list
?
os.listdir()
sẽ giúp bạn có mọi thứ trong thư mục - tệp và thư mục.
Nếu bạn muốn chỉ tệp, bạn có thể lọc phần này xuống bằng cách sử dụng os.path
:
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
hoặc bạn có thể sử dụng os.walk()
sẽ mang lại hai danh sách cho mỗi thư mục mà nó truy cập - chia thành các tệp và thư mục cho bạn. Nếu bạn chỉ muốn thư mục trên cùng, bạn có thể phá vỡ lần đầu tiên nó mang lại
from os import walk
f = []
for (dirpath, dirnames, filenames) in walk(mypath):
f.extend(filenames)
break
Và cuối cùng, như ví dụ đó cho thấy, thêm một danh sách vào danh sách khác, bạn có thể sử dụng .extend()
hoặc
>>> q = [1, 2, 3]
>>> w = [4, 5, 6]
>>> q = q + w
>>> q
[1, 2, 3, 4, 5, 6]
Cá nhân, tôi thích .extend()
Tôi thích sử dụng mô-đun glob
, vì nó phù hợp với mô hình và mở rộng.
import glob
print(glob.glob("/home/adam/*.txt"))
Nó sẽ trả về một danh sách với các tệp được yêu cầu:
['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]
import os
os.listdir("somedirectory")
sẽ trả về một danh sách tất cả các tập tin và thư mục trong "somedirectory".
Tôi cũng đã thực hiện một video ngắn ở đây: Python: cách lấy danh sách tệp trong thư mục
os.listdir ()
hoặc ..... cách lấy tất cả các tệp (và thư mục) trong thư mục hiện tại (Python 3)
Cách đơn giản nhất để có tệp trong thư mục hiện tại trong Python 3 là đây. Nó thực sự đơn giản; sử dụng mô-đun os
và chức năng listdir()
và bạn sẽ có tệp trong thư mục đó (và các thư mục cuối cùng có trong thư mục, nhưng bạn sẽ không có tệp trong thư mục con, vì bạn có thể sử dụng đi bộ trễ rồi).
>>> import os
>>> arr = os.listdir()
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
Sử dụng toàn cầu
Tôi thấy toàn cầu dễ dàng hơn để chọn tệp cùng loại hoặc có điểm chung. Hãy xem ví dụ sau :
import glob
txtfiles = []
for file in glob.glob("*.txt"):
txtfiles.append(file)
Sử dụng hiểu danh sách
import glob
mylist = [f for f in glob.glob("*.txt")]
Như bạn nhận thấy, bạn không có đường dẫn đầy đủ của tệp trong mã ở trên. Nếu bạn cần phải có đường dẫn tuyệt đối, bạn có thể sử dụng một chức năng khác của mô-đun os.path
có tên _getfullpathname
, đặt tệp mà bạn nhận được từ os.listdir()
làm đối số. Có nhiều cách khác để có đường dẫn đầy đủ, như chúng tôi sẽ kiểm tra sau (tôi đã thay thế, như được đề xuất bởi mexmex, _getfullpathname bằng abspath
).
>>> import os
>>> files_path = [os.path.abspath(x) for x in os.listdir()]
>>> files_path
['F:\\documenti\applications.txt', 'F:\\documenti\collections.txt']
walk
Tôi thấy điều này rất hữu ích để tìm nội dung trong nhiều thư mục và nó giúp tôi tìm một tệp mà tôi không nhớ tên:
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 ".docx" in file:
print(os.path.join(r, file))
os.listdir (): lấy tệp trong thư mục hiện tại (Python 2)
Trong Python 2, nếu bạn muốn danh sách các tệp trong thư mục hiện tại, bạn phải đưa ra đối số là '.' hoặc os.getcwd () trong phương thức os.listdir.
>>> import os
>>> arr = os.listdir('.')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
>>> # Method 1
>>> x = os.listdir('..')
# Method 2
>>> x= os.listdir('/')
>>> import os
>>> arr = os.listdir('F:\\python')
>>> arr
['$RECYCLE.BIN', 'work.txt', '3ebooks.txt', 'documents']
import os
x = os.listdir("./content")
>>> import os
>>> arr = next(os.walk('.'))[2]
>>> arr
['5bs_Turismo1.pdf', '5bs_Turismo1.pptx', 'esperienza.txt']
import glob
print(glob.glob("*"))
out:['content', 'start.py']
>>> 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)
>output
F:\\_python\\dict_class.py
F:\\_python\\programmi.txt
>>> [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 - nhận đường dẫn đầy đủ - tất cả các tệp trong thư mục con
x = [os.path.join(r,file) for r,d,f in os.walk("F:\\_python") for file in f]
>>>x
['F:\\_python\\dict.py', 'F:\\_python\\progr.txt', 'F:\\_python\\readl.py']
>>> arr_txt = [x for x in os.listdir() if x.endswith(".txt")]
>>> print(arr_txt)
['work.txt', '3ebooks.txt']
>>> import glob
>>> x = glob.glob("*.txt")
>>> x
['ale.txt', 'alunni2015.txt', 'assenze.text.txt', 'text2.txt', 'untitled.txt']
Nếu tôi cần đường dẫn tuyệt đối của các tập tin:
>>> 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
Nếu tôi muốn tất cả các tập tin trong thư mục:
>>> x = glob.glob("*")
import os.path
listOfFiles = [f for f in os.listdir() if os.path.isfile(f)]
print(listOfFiles)
> output
['a simple game.py', 'data.txt', 'decorator.py']
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
Nếu bạn muốn sử dụng danh sách hiểu
>>> flist = [p for p in pathlib.Path('.').iterdir() if p.is_file()]
* Bạn cũng có thể sử dụng chỉ pathlib.Path () thay vì pathlib.Path (".")
import pathlib
py = pathlib.Path().glob("*.py")
for file in py:
print(file)
đầu ra:
stack_overflow_list.py
stack_overflow_list_tkinter.py
import os
x = [i[2] for i in os.walk('.')]
y=[]
for t in x:
for f in t:
y.append(f)
>>> 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']
>>> import os
>>> x = next(os.walk('F://python'))[2]
>>> x
['calculator.bat','calculator.py']
>>> import os
>>> next(os.walk('F://python'))[1] # for the current dir use ('.')
['python3','others']
walk
>>> for r,d,f in os.walk("F:\_python"):
... for dirs in d:
... print(dirs)
...
.vscode
pyexcel
pyschool.py
subtitles
_metaprogramming
.ipynb_checkpoints
>>> import os
>>> x = [f.name for f in os.scandir() if f.is_file()]
>>> 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
>>>
Trong ví dụ này, chúng tôi tìm kiếm số lượng tệp được bao gồm trong tất cả các thư mục và thư mục con của nó.
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"))
> output
>'F:\\\python' : 12057 files'
Một tập lệnh để đặt hàng trong máy tính của bạn tìm tất cả các tệp thuộc loại (mặc định: pptx) và sao chép chúng trong một thư mục mới.
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("------------------------")
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')
> Output
_compiti18\Compito Contabilità 1\conti.txt
_compiti18\Compito Contabilità 1\modula4.txt
_compiti18\Compito Contabilità 1\moduloa4.txt
------------------------
==> Found in: `_compiti18` : 3 files
Trong trường hợp bạn muốn tạo một tệp txt với tất cả các tên tệp:
import os
mylist = ""
with open("filelist.txt", "w", encoding="utf-8") as file:
for eachfile in os.listdir():
mylist += eachfile + "\n"
file.write(mylist)
"""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")
Đây là một phiên bản ngắn hơn của mã trước đó. Thay đổi thư mục nơi bắt đầu tìm tệp nếu bạn cần bắt đầu từ vị trí khác. Mã này tạo ra 50 mb trên tệp văn bản trên máy tính của tôi với khoảng 500.000 dòng với các tệp có đường dẫn hoàn chỉnh.
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")
import os
def searchfiles(extension='.ttf'):
"Create a txt file with all the file of a type"
with open("file.txt", "w", encoding="utf-8") as filewrite:
for r, d, f in os.walk("C:\\"):
for file in f:
if file.endswith(extension):
filewrite.write(f"{r + file}\n")
# looking for ttf file (fonts)
searchfiles('ttf')
Một giải pháp một dòng để nhận chỉ danh sách các tệp (không có thư mục con):
filenames = next(os.walk(path))[2]
hoặc tên đường dẫn tuyệt đối:
paths = [os.path.join(path,fn) for fn in next(os.walk(path))[2]]
Nhận đường dẫn tệp đầy đủ từ một thư mục và tất cả các thư mục con của nó
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
sẽ in danh sách:
['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']
Nếu bạn muốn, bạn có thể mở và đọc nội dung hoặc chỉ tập trung vào các tệp có phần mở rộng ".dat" như trong mã dưới đây:
for f in full_file_paths:
if f.endswith(".dat"):
print f
/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat
Kể từ phiên bản 3.4, có tích hợp iterators cho việc này hiệu quả hơn nhiều so với os.listdir()
:
pathlib
: Mới trong phiên bản 3.4.
>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]
Theo PEP 428 , mục đích của pathlib
library là cung cấp một hệ thống phân cấp đơn giản của các lớp để xử lý các đường dẫn hệ thống tệp và các hoạt động chung mà người dùng thực hiện đối với chúng.
os.scandir()
: Mới trong phiên bản 3.5.
>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]
Lưu ý rằng os.walk()
sử dụng os.scandir()
thay vì os.listdir()
từ phiên bản 3.5 và tốc độ của nó đã tăng gấp 2-20 lần theo PEP 471 .
Tôi cũng khuyên bạn nên đọc bình luận của ShadowRanger bên dưới.
Khi câu hỏi được hỏi, tôi tưởng tượng rằng Python 2 , là LTS phiên bản, tuy nhiên các mẫu mã sẽ được chạy bởi Python 3 (. 5 ) (Tôi sẽ giữ chúng dưới dạng Python 2 tuân thủ càng tốt, đồng thời, bất kỳ mã nào thuộc về Python mà tôi sẽ đăng, là từ v3.5.4 - trừ khi có quy định khác). Điều đó có hậu quả liên quan đến một từ khóa khác trong câu hỏi: " thêm chúng vào danh sách ":
_>>> 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'>)
_
Các ví dụ sẽ dựa trên một thư mục có tên root_dir với cấu trúc sau (ví dụ này là cho Win , nhưng tôi đang sử dụng cùng một cây trên Lnx cũng vậy):
_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 = '.' )
Trả về một danh sách chứa tên của các mục trong thư mục được cung cấp bởi đường dẫn. Danh sách theo thứ tự tùy ý và không bao gồm các mục đặc biệt _
'.'
_ và _'..'
_ ...
_>>> 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']
_
Một ví dụ phức tạp hơn ( 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 __== "__main__":
main()
_
Ghi chú :
Đầu ra :
_(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 =)
Trả về một iterator của os.DirEntry các đối tượng tương ứng với các mục trong thư mục được cung cấp bởi path . Các mục được sinh ra theo thứ tự tùy ý và các mục đặc biệt _
'.'
_ và _'..'
_ không được bao gồm.Sử dụng scandir () thay vì listdir () có thể tăng đáng kể hiệu suất của mã cũng cần loại tệp hoặc thông tin thuộc tính tệp, vì os.DirEntry = các đối tượng phơi bày thông tin này nếu hệ điều hành cung cấp nó khi quét một thư mục. Tất cả các phương thức os.DirEntry có thể thực hiện cuộc gọi hệ thống, nhưng is_dir () và is_file () thường chỉ yêu cầu một cuộc gọi hệ thống cho các liên kết tượng trưng; os.DirEntry.stat () luôn yêu cầu một cuộc gọi hệ thống trên Unix nhưng chỉ yêu cầu một liên kết tượng trưng trên Windows.
_>>> 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
_
Ghi chú :
os.listdir
_[Python 3]: os. walk ( top, topdown = True, onerror = Không, followlinks = Sai )
Tạo tên tệp trong cây thư mục bằng cách đi bộ cây từ trên xuống hoặc từ dưới lên. Đối với mỗi thư mục trong cây bắt nguồn từ thư mục top (bao gồm top ), nó mang lại 3-Tuple (
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', [], [])
_
Ghi chú :
os.scandir
_ (_os.listdir
_ trên các phiên bản cũ hơn)[Python 3]: global. global ( tên đường dẫn, *, đệ quy = Sai ) ( [Python 3]: global. iglob ( tên đường dẫn, *, đệ quy = Sai ) )
Trả về một danh sách có thể trống các tên đường dẫn khớp với tên đường dẫn , phải là một chuỗi chứa một đặc tả đường dẫn. tên đường dẫn có thể là tuyệt đối (như _
/usr/src/Python-1.5/Makefile
_) hoặc họ hàng (như _../../Tools/*/*.gif
_) và có thể chứa các ký tự đại diện kiểu Shell. Các liên kết tượng trưng bị hỏng được bao gồm trong các kết quả (như trong Shell).
[.__.] ...
[.__.] Đã thay đổi trong phiên bản 3.5 : Hỗ trợ cho các quả cầu đệ quy bằng cách sử dụng _**
_ lu.
_>>> 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
_
Ghi chú :
os.listdir
_[Python 3]: class pathlib. Đường dẫn ( * pathsegments ) ( 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']
_
Ghi chú :
[Python 2]: dircache.listdir (đường dẫn) ( Python 2 chỉ có)
os.listdir
_ với bộ nhớ đệm_def 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]: ĐÃ ĐÓNG CỬA (3) qua - [Python 3]: ctypes - Thư viện hàm ngoại cho Python (POSIX cụ thể)
ctypes là một thư viện hàm ngoại cho Python. Nó cung cấp các kiểu dữ liệu tương thích C và cho phép gọi các hàm trong DLL hoặc thư viện dùng chung. Nó có thể được sử dụng để bọc các thư viện này trong Python thuần túy.
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 __== "__main__":
main()
_
Ghi chú :
os.walk
_ 's. Tôi không bận tâm làm cho nó đệ quy, nhưng bắt đầu từ mã hiện có, đó sẽ là một nhiệm vụ khá nhỏĐầu ra :
_[[email protected]:~/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 cụ thể)
Lấy danh sách tên tệp phù hợp, sử dụng API Unicode của Windows. Giao diện cho API FindFirstFileW/FindNextFileW/Tìm các hàm đóng.
_>>> 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']
_
Ghi chú :
win32file.FindFilesW
_ là một phần của [GitHub]: mhammond/pywin32 - Python cho Windows (pywin32) Tiện ích mở rộng , đó là một Python trình bao bọc WINAPI sGhi chú :
Mã có nghĩa là có thể di động (ngoại trừ những nơi nhắm mục tiêu đến một khu vực cụ thể - được đánh dấu) hoặc chéo:
Nhiều kiểu đường dẫn (tuyệt đối, họ hàng) đã được sử dụng trên các biến thể trên, để minh họa thực tế là "công cụ" được sử dụng linh hoạt theo hướng này
_os.listdir
_ và _os.scandir
_ sử dụng opendir / readdir / closeir ( [MS.Docs]: Hàm FindFirstFileW / [MS.Docs]: Hàm FindNextFileW / [MS.Docs]: Hàm FindClose =) (thông qua [GitHub]: python/cpython - (master) cpython/Modules/posixmodule.c )
_win32file.FindFilesW
_ cũng sử dụng các hàm đó ( Win cụ thể) (thông qua [GitHub]: mhammond/pywin32 - (chính) pywin32/win32/src/win32file .i )
_ get_dir_content (từ điểm # 1. ) có thể được thực hiện bằng bất kỳ cách tiếp cận nào trong số này (một số sẽ đòi hỏi nhiều công việc hơn và một số ít hơn)
filter_func=lambda x: True
_ (điều này không loại bỏ bất cứ thứ gì) và bên trong _ get_dir_content một cái gì đó như: if not filter_func(entry_with_path): continue
(nếu chức năng không thành công cho một mục nhập, nó sẽ bị bỏ qua ), nhưng mã càng phức tạp thì càng mất nhiều thời gian để thực thi Nota bene! Kể từ khi sử dụng đệ quy, tôi phải đề cập rằng tôi đã thực hiện một số thử nghiệm trên máy tính xách tay của mình ( Win 10 x64 ), hoàn toàn không liên quan đến vấn đề này và khi mức đệ quy đạt đến các giá trị ở đâu đó trong phạm vi (990 .. 1000) ( recursionlimit - 1000 (mặc định)), tôi đã nhận StackOverflow :). Nếu cây thư mục vượt quá giới hạn đó (tôi không phải là chuyên gia FS, vì vậy tôi không biết liệu điều đó có khả thi hay không), đó có thể là một vấn đề.
[.__.] Tôi cũng phải đề cập rằng tôi đã không cố gắng tăng recursionlimit vì tôi không có kinh nghiệm trong khu vực (tôi có thể tăng bao nhiêu trước khi phải tăng ngăn xếp ở mức OS), nhưng trên lý thuyết sẽ luôn có khả năng thất bại, nếu độ sâu dir lớn hơn mức cao nhất có thể recursionlimit (trên máy đó)
Các mẫu mã chỉ dành cho mục đích trình diễn. Điều đó có nghĩa là tôi đã không tính đến việc xử lý lỗi tài khoản (Tôi không nghĩ có bất kỳ thử / ngoại trừ / khác / cuối cùng khối), vì vậy mã không mạnh mẽ (lý do là: để giữ cho nó đơn giản và ngắn nhất có thể). Đối với sản xuất , cũng nên thêm xử lý lỗi
Chỉ sử dụng Python làm trình bao bọc
Hương vị nổi tiếng nhất mà tôi biết là cách tôi gọi là phương pháp quản trị viên hệ thống :
grep
/findstr
) hoặc định dạng đầu ra có thể được thực hiện ở cả hai bên, nhưng tôi sẽ không nhấn mạnh vào nó. Ngoài ra, tôi cố tình sử dụng _os.system
_ thay vì _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
_
Nói chung, nên tránh cách tiếp cận này, vì nếu một số định dạng đầu ra lệnh hơi khác nhau giữa OS phiên bản/hương vị, thì mã phân tích cũng phải được điều chỉnh; không đề cập đến sự khác biệt giữa các địa phương).
Tôi thực sự thích câu trả lời của adamk , đề nghị bạn sử dụng glob()
, từ mô-đun cùng tên. Điều này cho phép bạn có mô hình khớp với *
s.
Nhưng như những người khác đã chỉ ra trong các bình luận, glob()
có thể bị vấp phải các hướng chém không nhất quán. Để giải quyết vấn đề đó, tôi khuyên bạn cũng nên sử dụng các hàm join()
và expanduser()
trong mô-đun os.path
và có lẽ cả hàm getcwd()
trong mô-đun os
.
Ví dụ:
from glob import glob
# Return everything under C:\Users\admin that contains a folder called wlp.
glob('C:\Users\admin\*\wlp')
Ở trên là khủng khiếp - đường dẫn đã được mã hóa cứng và sẽ chỉ hoạt động trên Windows giữa tên ổ đĩa và \
s được mã hóa cứng vào đường dẫn.
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'))
Ở trên hoạt động tốt hơn, nhưng nó phụ thuộc vào tên thư mục Users
thường được tìm thấy trên Windows và không thường thấy trên các HĐH khác. Nó cũng phụ thuộc vào người dùng có một tên cụ thể, 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'))
Điều này hoạt động hoàn hảo trên tất cả các nền tảng.
Một ví dụ tuyệt vời khác hoạt động hoàn hảo trên các nền tảng và làm một cái gì đó hơi khác một chút:
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'))
Hy vọng những ví dụ này sẽ giúp bạn thấy sức mạnh của một vài chức năng bạn có thể tìm thấy trong các mô-đun thư viện Python tiêu chuẩn.
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
Nếu bạn đang tìm kiếm một triển khai Python của find , đây là một công thức tôi sử dụng khá thường xuyên:
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
Vì vậy, tôi đã tạo một gói PyPI trong số đó và cũng có kho GitHub . Tôi hy vọng rằng ai đó tìm thấy nó có khả năng hữu ích cho mã này.
Trả lại danh sách các filepath tuyệt đối, không lặp lại thành các thư mục con
L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]
Để có kết quả cao hơn, bạn có thể sử dụng phương thức
listdir()
của mô-đunos
cùng với trình tạo (trình tạo là trình lặp mạnh mẽ giữ trạng thái của nó, nhớ không?). Đoạn mã sau hoạt động tốt với cả hai phiên bản: Python 2 và Python 3.
Đây là một mã:
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)
Phương thức listdir()
trả về danh sách các mục nhập cho thư mục đã cho. Phương thức os.path.isfile()
trả về True
nếu mục nhập đã cho là một tệp. Và toán tử yield
thoát khỏi func nhưng vẫn giữ trạng thái hiện tại và nó chỉ trả về tên của mục nhập được phát hiện dưới dạng tệp. Tất cả những điều trên cho phép chúng ta lặp qua chức năng của trình tạo.
Hi vọng điêu nay co ich.
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
Ở đây tôi sử dụng một cấu trúc đệ quy.
Tôi giả sử rằng tất cả các tệp của bạn có định dạng *.txt
và được lưu trữ trong một thư mục có đường dẫn data/
.
Người ta có thể sử dụng global module của python
để liệt kê tất cả các tệp của thư mục và thêm chúng vào danh sách có tên fnames
, theo cách sau:
import glob
fnames = glob.glob("data/*.txt") #fnames: list data type
Một giáo viên thông thái đã nói với tôi một lần rằng:
Khi có một số cách được thiết lập để làm một cái gì đó, không có cách nào là tốt cho tất cả các trường hợp.
Do đó, tôi sẽ thêm một giải pháp cho tập hợp con của vấn đề: khá thường xuyên, chúng tôi chỉ muốn kiểm tra xem một tệp có khớp với chuỗi bắt đầu và chuỗi kết thúc hay không mà không đi vào thư mục con. Do đó, chúng tôi muốn một hàm trả về danh sách tên tệp, như:
filenames = dir_filter('foo/baz', radical='radical', extension='.txt')
Nếu bạn quan tâm đến việc khai báo hai hàm đầu tiên, điều này có thể được thực hiện:
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)]
Giải pháp này có thể dễ dàng khái quát hóa bằng các biểu thức thông thường (và bạn có thể muốn thêm một đối số pattern
, nếu bạn không muốn các mẫu của bạn luôn bám vào đầu hoặc cuối của tên tệp).
Sử dụng máy phát điện
import os
def get_files(search_path):
for (dirpath, _, filenames) in os.walk(search_path):
for filename in filenames:
yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
print(filename)
Bạn có thể sử dụng mã này để lấy iterator chạy trên toàn bộ đường dẫn của tệp (Thư mục + tên tệp).
import os
def get_iterator_all_files_name(dir_path):
for (dirpath, dirnames, filenames) in os.walk(dir_path):
for f in filenames:
yield os.path.join(dirpath, f)
Hoặc sử dụng nó, để có được nó trong danh sách.
import os
def get_list_all_files_name(dir_path):
all_files_path = []
for (dirpath, dirnames, filenames) in os.walk(dir_path):
for f in filenames:
all_files_path.append(os.path.join(dirpath, f))
return all_files_path
# -** coding: utf-8 -*-
import os
import traceback
print '\n\n'
def start():
address = "/home/ubuntu/Desktop"
try:
Folders = []
Id = 1
for item in os.listdir(address):
endaddress = address + "/" + item
Folders.append({'Id': Id, 'TopId': 0, 'Name': item, 'Address': endaddress })
Id += 1
state = 0
for item2 in os.listdir(endaddress):
state = 1
if state == 1:
Id = FolderToList(endaddress, Id, Id - 1, Folders)
return Folders
except:
print "___________________________ ERROR ___________________________\n" + traceback.format_exc()
def FolderToList(address, Id, TopId, Folders):
for item in os.listdir(address):
endaddress = address + "/" + item
Folders.append({'Id': Id, 'TopId': TopId, 'Name': item, 'Address': endaddress })
Id += 1
state = 0
for item in os.listdir(endaddress):
state = 1
if state == 1:
Id = FolderToList(endaddress, Id, Id - 1, Folders)
return Id
print start()
Sử dụng chức năng này nếu bạn muốn sử dụng một loại tệp khác hoặc lấy thư mục đầy đủ:
import os
def createList(foldername, fulldir = True, suffix=".jpg"):
file_list_tmp = os.listdir(foldername)
#print len(file_list_tmp)
file_list = []
if fulldir:
for item in file_list_tmp:
if item.endswith(suffix):
file_list.append(os.path.join(foldername, item))
else:
for item in file_list_tmp:
if item.endswith(suffix):
file_list.append(item)
return file_list
Một biến thể rất dễ đọc khác cho Python 3.4+ là sử dụng pathlib.Path.glob:
from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]
Thật đơn giản để làm cho cụ thể hơn, ví dụ: chỉ tìm các tệp nguồn Python không phải là liên kết tượng trưng, trong tất cả các thư mục con:
[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]
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
Đây là chức năng mục đích chung của tôi cho việc này. Nó trả về một danh sách các đường dẫn tệp chứ không phải tên tệp vì tôi thấy rằng nó hữu ích hơn. Nó có một vài đối số tùy chọn làm cho nó linh hoạt. Chẳng hạn, tôi thường sử dụng nó với các đối số như pattern='*.txt'
hoặc 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)]
Đối với python2: pip cài đặt rglob
import rglob
file_list=rglob.rglob("/home/base/dir/", "*")
print file_list
Tôi sẽ cung cấp một lớp lót mẫu trong đó có thể cung cấp loại đường dẫn và loại tệp làm đầu vào. Mã này trả về một danh sách tên tệp có phần mở rộng csv. Sử dụng . trong trường hợp tất cả các tập tin cần phải được trả lại. Điều này cũng sẽ quét đệ quy các thư mục con.
[y for x in os.walk(sourcePath) for y in glob(os.path.join(x[0], '*.csv'))]
Sửa đổi phần mở rộng tập tin và đường dẫn nguồn khi cần thiết.