Як я можу повторювати файли в заданому каталозі?


555

Мені потрібно перебрати всі .asmфайли всередині даної каталоги і зробити деякі дії над ними.

Як це можна зробити ефективно?

Відповіді:


807

Оригінальна відповідь:

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 3.6 вищевказаної відповіді, використовуючи os- якщо припустити, що у вас є шлях до каталогу як strоб'єкт у змінній, званій 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

Або рекурсивно, використовуючи 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)

1
Це просто здається, що список каталогів або файлів відразу під каталогом. Відповідь pedromateo нижче, здається, є рекурсивним переліком.
Джей Шет

8
Зауважте, що в Python 3.6 каталог очікується в байтах, і тоді listdir виплюне список імен файлів також у байтовому типі даних, тому ви не можете запускати кінця безпосередньо з ним. Цей блок коду слід змінити на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
Кім Стек

13
print(os.path.join(directory, filename))потрібно змінити, щоб print(os.path.join(directory_in_str, filename))змусити його працювати в python 3.6
Hugo Koopmans

54
Якщо ви бачите це в 2017 році або більше, os.scandir (dir_str) тепер доступний і набагато чистіший для використання. Не потрібно використовувати fsencode. for entry in os.scandir(path): print(entry.path)
коза

2
Віддаю перевагу , if filename.endswith((".asm", ".py")):щобif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio

152

Це дозволить повторити всі файли нащадків, а не лише безпосередні діти каталогу:

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)

3
Довідку про функцію os.walk можна знайти на наступному: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC

136

Ви можете спробувати використовувати глобальний модуль:

import glob

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

а оскільки Python 3.5 ви також можете шукати підкаталоги:

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

З документів:

Модуль glob знаходить усі назви шляхів, що відповідають заданому шаблону відповідно до правил, використовуваних оболонкою Unix, хоча результати повертаються у довільному порядку. Розширення тильди не робиться, але діапазони символів *,?, І символи, виражені [], будуть правильно узгоджені.


19

З Python 3.5 все набагато простіше з 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)

Використання scandir () замість listdir () може значно підвищити продуктивність коду, який також потребує інформації про тип файлу чи атрибути файлів, оскільки об'єкти os.DirEntry розкривають цю інформацію, якщо операційна система надає її під час сканування каталогу. Усі методи os.DirEntry можуть виконувати системний виклик, але is_dir () та is_file () зазвичай вимагають лише системного виклику для символічних посилань; os.DirEntry.stat () завжди вимагає системного виклику в Unix, але вимагає лише одного для символічних посилань у Windows.


entryє posix.DirEntry типу з купою зручних методів , таких як entry.is_dir(), is_file(),is_symlink()
crypdick

17

Python 3.4 і пізніші пропозиції пропонують pathlib у стандартній бібліотеці. Ви можете зробити:

from pathlib import Path

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

Або якщо ви не любите розуміння списку:

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

Path об'єкти легко перетворюються на рядки.


9

Ось як я повторюю файли в 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

НІхто з цих технологій не гарантує жодних замовлень ІТЕРАЦІЇ

Так, супер непередбачувано. Зауважте, що я сортую назви файлів, що важливо, якщо порядок файлів має значення, тобто для відеокадрів або збору даних, залежних від часу. Не забудьте ввести свої індекси у свої імена файлів!


Не завжди сортується ... im1, im10, im11 ..., im2 ... Інакше корисний підхід. from pkg_resources import parse_versionі filenames.sort(key=parse_version)зробив це.
Гастур

5

Ви можете використовувати glob для посилання на каталог та список:

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)

Для отримання списку всього каталогу в масиві ви можете використовувати os :

os.listdir(directory)

4

Я ще не дуже задоволений цією реалізацією, мені хотілося створити спеціальний конструктор, який робить DirectoryIndex._make(next(os.walk(input_path)))таке, що ви можете просто пройти шлях, для якого потрібно перелічити файл. Правки вітаємо!

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)

2

Мені дуже подобається використовувати scandirдирективу, вбудовану в osбібліотеку. Ось робочий приклад:

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.")

дублікат відповіді
crypdick
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.