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?

talnicolas
sumber
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 '.'.

Adam Rosenfield
sumber
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())
Joshmaker
sumber
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
bersih
sumber
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
15

Joshmaker memiliki solusi yang tepat untuk pertanyaan Anda.
Bagaimana cara mengabaikan file tersembunyi menggunakan os.listdir ()?

Namun dalam Python 3, disarankan untuk menggunakan pathlib daripada os.

from pathlib import Path 
visible_files = [
    file for file in Path(".").iterdir() if not file.name.startswith(".")
]
sampah
sumber
14

glob :

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

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

Josh Lee
sumber
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('*')
pengguna 923227
sumber
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('.'))
amenbo
sumber