سؤال

أحاول الحصول على قائمة بالملفات في دليل باستخدام Python، لكنني لا أريد قائمة بجميع الملفات.

ما أريده بشكل أساسي هو القدرة على فعل شيء مثل ما يلي ولكن باستخدام Python وعدم تنفيذ LS.

ls 145592*.jpg

إذا لم يكن هناك طريقة مدمجة لهذا، فأنا أفكر حاليا في كتابة حلقة للتكرار من خلال نتائج os.listdir() وللوقع جميع الملفات المطابقة قائمة جديدة.

ومع ذلك، هناك الكثير من الملفات في هذا الدليل، وبالتالي آمل أن تكون هناك طريقة أكثر كفاءة (أو طريقة مدمجة).

هل كانت مفيدة؟

المحلول

نصائح أخرى

glob.glob() هي بالتأكيد طريقة للقيام بذلك (حسب إجناسيو). ومع ذلك، إذا كنت بحاجة إلى مطابقة أكثر تعقيدا، يمكنك القيام بذلك بمهمة قائمة و re.match(), ، شيء مثل ذلك:

files = [f for f in os.listdir('.') if re.match(r'[0-9]+.*\.jpg', f)]

أكثر مرونة، ولكن كما تريد، أقل كفاءة.

أبقيها بسيطة:

import os
relevant_path = "[path to folder]"
included_extensions = ['jpg','jpeg', 'bmp', 'png', 'gif']
file_names = [fn for fn in os.listdir(relevant_path)
              if any(fn.endswith(ext) for ext in included_extensions)]

أفضل هذا الشكل من الفهم لأنه يقرأ جيدا باللغة الإنجليزية.

قرأت السطر الرابع ك: لكل FN في Os.ListDir على طريقي، أعطني فقط تلك التي تتطابق مع أي من ملحقاتي المضمنة.

قد يكون من الصعب على مبرمجي Python المبتدئين أن يعتادوا حقا على استخدام الفهم للقائمة للتصفية، ويمكن أن يكون لها بعض الذاكرة النفقات العامة لمجموعات بيانات كبيرة جدا، ولكن لإدراج دليل دليل وغيرها من مهام تصفية السلسلة الأخرى، يؤدي قائمة الفهم إلى أكثر نظافة رمز وثيق.

الشيء الوحيد في هذا التصميم هو أنه لا يحميك من ارتكاب خطأ تمرير سلسلة بدلا من قائمة. على سبيل المثال، إذا قمت بتحويل سلسلة إلى قائمة إلى قائمة وينتهي الأمر بفحص جميع أحرف السلسلة، فيمكنك الانتهاء من الحصول على مجموعة من الإيجابيات الخاطئة.

ولكن من الأفضل أن يكون لديك مشكلة سهلة الإصلاح من الحل الذي يصعب فهمه.

خيار اخر:

>>> import os, fnmatch
>>> fnmatch.filter(os.listdir('.'), '*.py')
['manage.py']

https://docs.python.org/3/library/fnmatch.html.

استخدم Os.Walk لإدراج ملفاتك بشكل متكرر

import os
root = "/home"
pattern = "145992"
alist_filter = ['jpg','bmp','png','gif'] 
path=os.path.join(root,"mydir_to_scan")
for r,d,f in os.walk(path):
    for file in f:
        if file[-3:] in alist_filter and pattern in file:
            print os.path.join(root,file)

رمز أولي

import glob
import fnmatch
import pathlib
import os

pattern = '*.py'
path = '.'

الحل 1. - استخدم "Glob"

# lookup in current dir
glob.glob(pattern)

In [2]: glob.glob(pattern)
Out[2]: ['wsgi.py', 'manage.py', 'tasks.py']

الحل 2 - استخدم "OS" + "FNMatch"

البديل 2.1. - البحث في دير الحالي

# lookup in current dir
fnmatch.filter(os.listdir(path), pattern)

In [3]: fnmatch.filter(os.listdir(path), pattern)
Out[3]: ['wsgi.py', 'manage.py', 'tasks.py']

البديل 2.2. - البحث العودية

# lookup recursive
for dirpath, dirnames, filenames in os.walk(path):

    if not filenames:
        continue

    pythonic_files = fnmatch.filter(filenames, pattern)
    if pythonic_files:
        for file in pythonic_files:
            print('{}/{}'.format(dirpath, file))

نتيجة

./wsgi.py
./manage.py
./tasks.py
./temp/temp.py
./apps/diaries/urls.py
./apps/diaries/signals.py
./apps/diaries/actions.py
./apps/diaries/querysets.py
./apps/library/tests/test_forms.py
./apps/library/migrations/0001_initial.py
./apps/polls/views.py
./apps/polls/formsets.py
./apps/polls/reports.py
./apps/polls/admin.py

الحل 3. - استخدم "Pathlib"

# lookup in current dir
path_ = pathlib.Path('.')
tuple(path_.glob(pattern))

# lookup recursive
tuple(path_.rglob(pattern))

ملاحظات:

  1. اختبارها على بيثون 3.4
  2. تمت إضافة وحدة "Pathlib" فقط في Python 3.4
  3. وأضاف Python 3.5 ميزة بحث متكرر مع Glob.globhttps://docs.python.org/3.5/library/glob.html#lob.glob.. وبعد نظرا لأن جهازي مثبت مع Python 3.4، لم أختبر ذلك.

مرشح مع glob وحدة:

استيراد الأرض

import glob

البطاقات البرية:

files=glob.glob("data/*")
print(files)

Out:

['data/ks_10000_0', 'data/ks_1000_0', 'data/ks_100_0', 'data/ks_100_1',
'data/ks_100_2', 'data/ks_106_0', 'data/ks_19_0', 'data/ks_200_0', 'data/ks_200_1', 
'data/ks_300_0', 'data/ks_30_0', 'data/ks_400_0', 'data/ks_40_0', 'data/ks_45_0', 
'data/ks_4_0', 'data/ks_500_0', 'data/ks_50_0', 'data/ks_50_1', 'data/ks_60_0', 
'data/ks_82_0', 'data/ks_lecture_dp_1', 'data/ks_lecture_dp_2']

امتداد fiter .txt:

files = glob.glob("/home/ach/*/*.txt")

شخصية واحدة

glob.glob("/home/ach/file?.txt")

عدد يتراوح

glob.glob("/home/ach/*[0-9]*")

نطاقات الأبجدية

glob.glob("/home/ach/[a-c]*")

قد ترغب أيضا في نهج أكثر رفيعة المستوى (لقد قمت بتنفيذ وتعبئتها findtools.):

from findtools.find_files import (find_files, Match)


# Recursively find all *.txt files in **/home/**
txt_files_pattern = Match(filetype='f', name='*.txt')
found_files = find_files(path='/home', match=txt_files_pattern)

for found_file in found_files:
    print found_file

يمكن تثبيتها مع

pip install findtools
import os

dir="/path/to/dir"
[x[0]+"/"+f for x in os.walk(dir) for f in x[2] if f.endswith(".jpg")]

هذا سيمنحك قائمة بملفات JPG مع مسارها الكامل. يمكنك استبدال. x[0]+"/"+f مع f لأسماء الملفات فقط. يمكنك أيضا استبدال f.endswith(".jpg") مع أي حالة سلسلة ترغب فيها.

أسماء الملفات مع ملحقات "JPG" و "PNG" في "المسار / إلى / الصور":

import os
accepted_extensions = ["jpg", "png"]
filenames = [fn for fn in os.listdir("path/to/images") if fn.split(".")[-1] in accepted_extensions]

يمكنك استخدام Pathlib. هذا متاح في مكتبة Python القياسية 3.4 وما فوق.

from pathlib import Path

files = [f for f in Path.cwd().iterdir() if f.match("145592*.jpg")]

يمكنك استخدام subprocess.check_ouput () كما

import subprocess

list_files = subprocess.check_output("ls 145992*.jpg", shell=True) 

بالطبع، يمكن أن تكون السلسلة بين علامات الاقتباس أي شيء تريد تنفيذه في القشرة، وتخزين الإخراج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top