Bagaimana cara mengabaikan file tersembunyi menggunakan os.listdir ()?


88

Skrip python saya mengeksekusi di os.listdir(path)mana jalurnya adalah antrian yang berisi arsip yang perlu saya tangani satu per satu.

Masalahnya adalah saya mendapatkan daftar dalam array dan kemudian saya hanya melakukan yang sederhana array.pop(0). Itu bekerja dengan baik sampai saya menempatkan proyek dalam subversi. Sekarang saya mendapatkan .svnfolder tersebut di array saya dan tentu saja itu membuat aplikasi saya macet.

Jadi, inilah pertanyaan saya: apakah ada fungsi yang mengabaikan file tersembunyi saat menjalankan os.listdir()dan jika tidak, apa cara terbaik?


Anda mungkin juga ingin menghindari folder denganos.path.isdir()
HashRocketSyntax

Jawaban:


103

Anda dapat menulisnya sendiri:

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

Atau Anda dapat menggunakan glob :

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

Salah satu dari ini akan mengabaikan semua nama file yang dimulai dengan '.'.


1
fungsi yang diusulkan listdir_nohiddentidak cukup kompatibel os.listdir, karena penggunaan yieldmenjadikannya sebagai generator. Sebaliknya itu harus dijalankan melalui daftar keluaran dari os.listdirdan menghapus entri yang dimulai dengan '.'
Milo Wielondek

3
@ 0sh: Mengapa harus menghapus sesuatu pada tempatnya? Cukup tentukan fungsi baru yang berfungsi list(listdir_nohidden(path))dan fungsi baru tersebut benar-benar kompatibel os.listdir.
abarnert

50

Ini adalah pertanyaan lama, tetapi sepertinya tidak ada jawaban yang jelas untuk menggunakan pemahaman daftar, jadi saya menambahkannya di sini untuk kelengkapan:

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

Sebagai catatan tambahan, status dokumen listdirakan mengembalikan hasil dalam 'urutan arbitrer' tetapi kasus penggunaan yang umum adalah meminta mereka diurutkan menurut abjad. Jika Anda ingin isi direktori diurutkan menurut abjad tanpa menggunakan huruf besar, Anda dapat menggunakan:

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

5
key=lambda f: f.lower()dapat ditulis tanpa lambda:key=str.lower
Jean-François Fabre

2
Untuk menggabungkan keduanya:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

19

Di Windows, Linux, dan 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
seharusnya juga berfungsi di Mac, file tersembunyi dimulai dari sana dengan '.' demikian juga.
Verena Haunschmid

2
Ini adalah satu-satunya jawaban portabel, kerja bagus, tetapi jawaban lain memberikan pembungkus lengkap untuk os.listdir jadi ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

glob :

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

( globmengklaim menggunakan listdirdan di fnmatchbawah kap, tetapi juga memeriksa petunjuk '.', bukan dengan menggunakan fnmatch.)


6

Saya pikir itu terlalu banyak pekerjaan untuk melewati semua item dalam satu lingkaran. Saya lebih suka sesuatu yang lebih sederhana seperti ini:

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

Jika direktori berisi lebih dari satu file tersembunyi , ini dapat membantu:

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

untuk kemandirian platform seperti yang disebutkan @Josh, glob berfungsi dengan baik:

import glob
glob.glob('*')

Itu hanya berfungsi jika Anda memiliki satu file tersembunyi, dan Anda tahu namanya. Bagaimana jika direktori berisi lusinan file tersembunyi, dengan nama sewenang-wenang yang tidak dapat Anda ketahui sebelumnya?
FeRD

Hai @FeRD, Ya. Ketika saya melakukan pemrosesan batch / backlog di mac, saya meletakkan semua file di folder baru dan .DS_Storedibuat secara otomatis. Ketika saya membuat zip semua file dan mendorongnya ke server .DS_Storejuga akan ditambahkan. Jika ada berbagai file tersembunyi maka Anda dapat mencobaos.system('ls -1')
pengguna 923227

Bukan lintas platform. os.popen('ls -1').read()tidak akan berfungsi di Windows. Itulah inti dari os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.