Làm cách nào để bỏ qua các tệp ẩn bằng os.listdir ()?


87

Tập lệnh python của tôi thực thi một os.listdir(path)trong đó đường dẫn là một hàng đợi chứa các kho lưu trữ mà tôi cần xử lý từng cái một.

Vấn đề là tôi đang nhận danh sách trong một mảng và sau đó tôi chỉ làm một việc đơn giản array.pop(0). Nó hoạt động tốt cho đến khi tôi đặt dự án vào tình trạng lật đổ. Bây giờ tôi nhận được .svnthư mục trong mảng của mình và tất nhiên nó làm cho ứng dụng của tôi gặp sự cố.

Vì vậy, đây là câu hỏi của tôi: có một hàm nào đó bỏ qua các tệp ẩn khi thực hiện một os.listdir()và nếu không thì đâu sẽ là cách tốt nhất?

Câu trả lời:


102

Bạn có thể tự viết một cái:

def listdir_nohidden(path):
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

Hoặc bạn có thể sử dụng một hình cầu :

def listdir_nohidden(path):
    return glob.glob(os.path.join(path, '*'))

Một trong hai cách này sẽ bỏ qua tất cả các tên tệp bắt đầu bằng '.'.


1
chức năng được đề xuất listdir_nohiddenkhông hoàn toàn tương thích với os.listdir, vì việc sử dụng yieldlàm cho nó trở thành một bộ tạo. Thay vào đó, nó sẽ chạy qua danh sách đầu ra từ os.listdirvà xóa các mục bắt đầu bằng '.'
Milo Wielondek

3
@ 0sh: Tại sao nó phải loại bỏ mọi thứ tại chỗ? Chỉ cần xác định một chức năng mới list(listdir_nohidden(path))và chức năng mới đó tương thích chính xác với os.listdir.
abarnert

47

Đây là một câu hỏi cũ, nhưng có vẻ như nó thiếu câu trả lời rõ ràng khi sử dụng khả năng hiểu danh sách, vì vậy tôi sẽ thêm nó vào đây để hoàn thiện:

[f for f in os.listdir(path) if not f.startswith('.')]

Lưu ý thêm, trạng thái tài liệu listdirsẽ trả về kết quả theo 'thứ tự tùy ý' nhưng trường hợp sử dụng phổ biến là sắp xếp chúng theo thứ tự bảng chữ cái. Nếu bạn muốn nội dung thư mục được sắp xếp theo thứ tự bảng chữ cái mà không liên quan đến viết hoa, bạn có thể sử dụng:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())

5
key=lambda f: f.lower()có thể được viết mà không có lambda:key=str.lower
Jean-François Fabre

2
Để kết hợp cả hai:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

18

Trên Windows, Linux và OS X:

if os.name == 'nt':
    import win32api, win32con


def folder_is_hidden(p):
    if os.name== 'nt':
        attribute = win32api.GetFileAttributes(p)
        return attribute & (win32con.FILE_ATTRIBUTE_HIDDEN | win32con.FILE_ATTRIBUTE_SYSTEM)
    else:
        return p.startswith('.') #linux-osx

2
cũng sẽ hoạt động trên máy Mac, các tệp ẩn bắt đầu ở đó bằng '.' cũng.
Verena Haunschmid

2
Đây là câu trả lời duy xách tay, công việc tuyệt vời, nhưng câu trả lời khác cung cấp một wrapper đầy đủ cho os.listdir như vậy ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

cầu :

>>> import glob
>>> glob.glob('*')

( globtuyên bố sử dụng listdirfnmatchche giấu, nhưng nó cũng kiểm tra sự dẫn đầu '.', không phải bằng cách sử dụng fnmatch.)


6

Tôi nghĩ rằng nó là quá nhiều công việc để xem qua tất cả các mục trong một vòng lặp. Tôi muốn một cái gì đó đơn giản hơn như thế này:

lst = os.listdir(path)
if '.DS_Store' in lst:
    lst.remove('.DS_Store')

Nếu thư mục chứa nhiều hơn một tệp ẩn , thì điều này có thể giúp:

all_files = os.popen('ls -1').read()
lst = all_files.split('\n')

về tính độc lập của nền tảng như @Josh đã đề cập, cầu hoạt động tốt:

import glob
glob.glob('*')

Điều đó chỉ hoạt động nếu bạn có một tệp ẩn bạn biết tên của nó. Điều gì sẽ xảy ra nếu thư mục chứa hàng tá tệp ẩn, với tên tùy ý mà bạn không thể biết trước?
FeRD

Xin chào @FeRD, Vâng. Khi tôi đang xử lý hàng loạt / tồn đọng trên máy mac, tôi đặt tất cả các tệp vào thư mục mới và .DS_Stoređược tạo tự động. Khi tôi nén tất cả các tệp và đẩy nó lên máy chủ .DS_Storecũng được thêm vào. Nếu có các tập tin ẩn khác nhau thì có thể bạn có thể thửos.system('ls -1')
sử dụng 923.227

Không đa nền tảng. os.popen('ls -1').read()sẽ không hoạt động trên Windows. Đó là toàn bộ điểm của os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.