Bagaimana saya bisa mengulangi file dalam direktori yang diberikan?

556

Saya perlu mengulangi semua .asmfile di dalam direktori yang diberikan dan melakukan beberapa tindakan pada mereka.

Bagaimana ini bisa dilakukan dengan cara yang efisien?

Itzik984
sumber

Jawaban:

808

Jawaban asli:

import os

for filename in os.listdir(directory):
    if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
        continue
    else:
        continue

Python versi 3.6 dari jawaban di atas, menggunakan os- dengan asumsi bahwa Anda memiliki jalur direktori sebagai strobjek dalam variabel yang disebut directory_in_str:

import os

directory = os.fsencode(directory_in_str)

for file in os.listdir(directory):
     filename = os.fsdecode(file)
     if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
         continue
     else:
         continue

Atau secara rekursif, menggunakan pathlib:

from pathlib import Path

pathlist = Path(directory_in_str).glob('**/*.asm')
for path in pathlist:
     # because path is object not string
     path_in_str = str(path)
     # print(path_in_str)
anselm
sumber
1
Ini sepertinya daftar direktori atau file segera di bawah direktori. Jawaban oleh pedromateo di bawah ini tampaknya melakukan daftar rekursif.
Jay Sheth
8
Harap dicatat bahwa dalam direktori Python 3.6 diharapkan dalam byte dan kemudian listdir akan memuntahkan daftar nama file juga dalam tipe data byte sehingga Anda tidak dapat menjalankan endswith langsung di atasnya. Blok kode ini harus diubah menjadidirectory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
Kim Stacks
13
print(os.path.join(directory, filename))perlu diubah untuk print(os.path.join(directory_in_str, filename))membuatnya bekerja di python 3.6
Hugo Koopmans
54
Jika Anda melihat ini pada tahun 2017 atau lebih, os.scandir (dir_str) sekarang tersedia dan jauh lebih bersih untuk digunakan. Tidak perlu untuk fsencode. for entry in os.scandir(path): print(entry.path)
kambing
2
Lebih if filename.endswith((".asm", ".py")):keif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio
152

Ini akan beralih ke semua file turunan, bukan hanya anak-anak langsung dari direktori:

import os

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        #print os.path.join(subdir, file)
        filepath = subdir + os.sep + file

        if filepath.endswith(".asm"):
            print (filepath)
pedromateo
sumber
3
Referensi untuk fungsi os.walk ditemukan di berikut ini: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC
136

Anda dapat mencoba menggunakan modul glob :

import glob

for filepath in glob.iglob('my_dir/*.asm'):
    print(filepath)

dan karena Python 3.5 Anda dapat mencari subdirektori juga:

glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']

Dari dokumen:

Modul glob menemukan semua nama path yang cocok dengan pola yang ditentukan sesuai dengan aturan yang digunakan oleh shell Unix, meskipun hasilnya dikembalikan dalam urutan acak. Tidak ada ekspansi tilde yang dilakukan, tetapi rentang karakter *,?, Dan yang dinyatakan dengan [] akan dicocokkan dengan benar.

Doboy
sumber
19

Sejak Python 3.5, banyak hal lebih mudah dengan os.scandir ( )

with os.scandir(path) as it:
    for entry in it:
        if entry.name.endswith(".asm") and entry.is_file():
            print(entry.name, entry.path)

Menggunakan scandir () sebagai ganti listdir () dapat secara signifikan meningkatkan kinerja kode yang juga memerlukan tipe file atau informasi atribut file, karena objek os.DirEntry memaparkan informasi ini jika sistem operasi menyediakannya ketika memindai direktori. Semua metode os.DirEntry dapat melakukan panggilan sistem, tetapi is_dir () dan is_file () biasanya hanya memerlukan panggilan sistem untuk tautan simbolik; os.DirEntry.stat () selalu membutuhkan panggilan sistem di Unix tetapi hanya membutuhkan satu untuk tautan simbolis pada Windows.

crypdick
sumber
entryadalah posix.DirEntry jenis dengan banyak metode yang berguna seperti entry.is_dir(), is_file(),is_symlink()
crypdick
17

Python 3.4 dan yang lebih baru menawarkan pathlib di pustaka standar. Anda bisa melakukannya:

from pathlib import Path

asm_pths = [pth for pth in Path.cwd().iterdir()
            if pth.suffix == '.asm']

Atau jika Anda tidak suka daftar pemahaman:

asm_paths = []
for pth in Path.cwd().iterdir():
    if pth.suffix == '.asm':
        asm_pths.append(pth)

Path objek dapat dengan mudah dikonversi menjadi string.

Greg
sumber
9

Inilah cara saya mengulangi file dengan Python:

import os

path = 'the/name/of/your/path'

folder = os.fsencode(path)

filenames = []

for file in os.listdir(folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
        filenames.append(filename)

filenames.sort() # now you have the filenames and can do something with them

TIDAK ADA JAMINAN TEKNIK INI PESANAN APA PUN

Yup, super tidak terduga. Perhatikan bahwa saya mengurutkan nama file, yang penting jika urutan file penting, yaitu untuk bingkai video atau pengumpulan data tergantung waktu. Pastikan untuk menempatkan indeks di nama file Anda!

Daniel McGrath
sumber
Tidak selalu diurutkan ... im1, im10, im11 ..., im2 ... Jika tidak, pendekatan yang bermanfaat. from pkg_resources import parse_versiondan filenames.sort(key=parse_version)berhasil.
Hastur
5

Anda dapat menggunakan glob untuk merujuk direktori dan daftar:

import glob
import os

#to get the current working directory name
cwd = os.getcwd()
#Load the images from images folder.
for f in glob.glob('images\*.jpg'):   
    dir_name = get_dir_name(f)
    image_file_name = dir_name + '.jpg'
    #To print the file name with path (path will be in string)
    print (image_file_name)

Untuk mendapatkan daftar semua direktori dalam array, Anda dapat menggunakan os :

os.listdir(directory)
MENYALAK
sumber
4

Saya belum cukup puas dengan penerapan ini, saya ingin memiliki konstruktor khusus yang berfungsi DirectoryIndex._make(next(os.walk(input_path)))agar Anda dapat melewati jalur yang Anda inginkan dari daftar file. Suntingan selamat datang!

import collections
import os

DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])

for file_name in DirectoryIndex(*next(os.walk('.'))).files:
    file_path = os.path.join(path, file_name)
ThorSummoner
sumber
2

Saya sangat suka menggunakan scandirarahan yang dibangun ke osperpustakaan. Berikut ini contoh kerjanya:

import os

i = 0
with os.scandir('/usr/local/bin') as root_dir:
    for path in root_dir:
        if path.is_file():
            i += 1
            print(f"Full path is: {path} and just the name is: {path.name}")
print(f"{i} files scanned successfully.")
jamescampbell
sumber
duplikat jawaban
crypdick