قائمة شجرة الدليل في بايثون
-
02-07-2019 - |
سؤال
كيف يمكنني الحصول على قائمة بجميع الملفات (والأدلة) في دليل معين في بايثون؟
المحلول
هذه طريقة لاجتياز كل ملف ودليل في شجرة الدليل:
import os
for dirname, dirnames, filenames in os.walk('.'):
# print path to all subdirectories first.
for subdirname in dirnames:
print(os.path.join(dirname, subdirname))
# print path to all filenames.
for filename in filenames:
print(os.path.join(dirname, filename))
# Advanced usage:
# editing the 'dirnames' list will stop os.walk() from recursing into there.
if '.git' in dirnames:
# don't go into any .git directories.
dirnames.remove('.git')
نصائح أخرى
يمكنك استخدام
os.listdir(path)
للرجوع إليها والمزيد من وظائف نظام التشغيل، انظر هنا:
- مستندات بايثون 2: https://docs.python.org/2/library/os.html#os.listdir
- مستندات بايثون 3: https://docs.python.org/3/library/os.html#os.listdir
إليك وظيفة مساعدة أستخدمها كثيرًا:
import os
def listdir_fullpath(d):
return [os.path.join(d, f) for f in os.listdir(d)]
import os
for filename in os.listdir("C:\\temp"):
print filename
إذا كنت بحاجة إلى قدرات الضرب، فهناك وحدة لذلك أيضًا.على سبيل المثال:
import glob
glob.glob('./[0-9].*')
سيعود شيء مثل:
['./1.gif', './2.txt']
انظر الوثائق هنا.
جرب هذا:
import os
for top, dirs, files in os.walk('./'):
for nm in files:
print os.path.join(top, nm)
للملفات الموجودة في دليل العمل الحالي دون تحديد مسار
بايثون 2.7:
import os
os.listdir(os.getcwd())
بايثون 3.x:
import os
os.listdir()
شكرًا لستام كالي للتعليق على python 3.x
تنفيذ العودية
import os
def scan_dir(dir):
for name in os.listdir(dir):
path = os.path.join(dir, name)
if os.path.isfile(path):
print path
else:
scan_dir(path)
لقد كتبت نسخة طويلة، مع جميع الخيارات التي قد أحتاجها: http://sam.nipl.net/code/python/find.py
أعتقد أنه سيكون مناسبًا هنا أيضًا:
#!/usr/bin/env python
import os
import sys
def ls(dir, hidden=False, relative=True):
nodes = []
for nm in os.listdir(dir):
if not hidden and nm.startswith('.'):
continue
if not relative:
nm = os.path.join(dir, nm)
nodes.append(nm)
nodes.sort()
return nodes
def find(root, files=True, dirs=False, hidden=False, relative=True, topdown=True):
root = os.path.join(root, '') # add slash if not there
for parent, ldirs, lfiles in os.walk(root, topdown=topdown):
if relative:
parent = parent[len(root):]
if dirs and parent:
yield os.path.join(parent, '')
if not hidden:
lfiles = [nm for nm in lfiles if not nm.startswith('.')]
ldirs[:] = [nm for nm in ldirs if not nm.startswith('.')] # in place
if files:
lfiles.sort()
for nm in lfiles:
nm = os.path.join(parent, nm)
yield nm
def test(root):
print "* directory listing, with hidden files:"
print ls(root, hidden=True)
print
print "* recursive listing, with dirs, but no hidden files:"
for f in find(root, dirs=True):
print f
print
if __name__ == "__main__":
test(*sys.argv[1:])
بطانة لطيفة لسرد الملفات بشكل متكرر فقط.لقد استخدمت هذا في توجيه setup.py package_data الخاص بي:
import os
[os.path.join(x[0],y) for x in os.walk('<some_directory>') for y in x[2]]
أعرف أن هذه ليست الإجابة على السؤال، ولكنها قد تكون مفيدة
بالنسبة لبيثون 2
#!/bin/python2
import os
def scan_dir(path):
print map(os.path.abspath, os.listdir(pwd))
بالنسبة لبيثون 3
بالنسبة للمرشح والخريطة، تحتاج إلى لفهما باستخدام القائمة ()
#!/bin/python3
import os
def scan_dir(path):
print(list(map(os.path.abspath, os.listdir(pwd))))
التوصية الآن هي أن تستبدل استخدامك للخريطة والتصفية بتعبيرات المولدات أو فهم القائمة:
#!/bin/python
import os
def scan_dir(path):
print([os.path.abspath(f) for f in os.listdir(path)])
إليك نسخة Pythonic ذات سطر واحد:
import os
dir = 'given_directory_name'
filenames = [os.path.join(os.path.dirname(os.path.abspath(__file__)),dir,i) for i in os.listdir(dir)]
يسرد هذا الرمز المسار الكامل لجميع الملفات والدلائل في اسم الدليل المحدد.
هنا خيار آخر.
os.scandir(path='.')
تقوم بإرجاع مكرر لكائنات os.DirEntry المقابلة للإدخالات (مع معلومات سمة الملف) في الدليل المحدد بواسطة المسار.
مثال:
with os.scandir(path) as it:
for entry in it:
if not entry.name.startswith('.'):
print(entry.name)
يمكن أن يؤدي استخدام scandir() بدلاً من listdir() إلى زيادة أداء التعليمات البرمجية بشكل كبير والتي تحتاج أيضًا إلى معلومات حول نوع الملف أو سمة الملف, لأن كائنات os.DirEntry تكشف هذه المعلومات إذا كان نظام التشغيل يوفرها عند فحص الدليل.قد تقوم جميع توابع os.DirEntry باستدعاء النظام، لكن is_dir() وis_file() عادةً ما تتطلب استدعاء نظام للارتباطات الرمزية فقط؛يتطلب os.DirEntry.stat() دائمًا استدعاء نظام على نظام Unix ولكنه يتطلب استدعاء واحد فقط للارتباطات الرمزية على Windows.
#import modules
import os
_CURRENT_DIR = '.'
def rec_tree_traverse(curr_dir, indent):
"recurcive function to traverse the directory"
#print "[traverse_tree]"
try :
dfList = [os.path.join(curr_dir, f_or_d) for f_or_d in os.listdir(curr_dir)]
except:
print "wrong path name/directory name"
return
for file_or_dir in dfList:
if os.path.isdir(file_or_dir):
#print "dir : ",
print indent, file_or_dir,"\\"
rec_tree_traverse(file_or_dir, indent*2)
if os.path.isfile(file_or_dir):
#print "file : ",
print indent, file_or_dir
#end if for loop
#end of traverse_tree()
def main():
base_dir = _CURRENT_DIR
rec_tree_traverse(base_dir," ")
raw_input("enter any key to exit....")
#end of main()
if __name__ == '__main__':
main()
FYI أضف مرشحًا للتمديد أو نظام تشغيل ملف EXT
path = '.'
for dirname, dirnames, filenames in os.walk(path):
# print path to all filenames with extension py.
for filename in filenames:
fname_path = os.path.join(dirname, filename)
fext = os.path.splitext(fname_path)[1]
if fext == '.py':
print fname_path
else:
continue
import os, sys
#open files in directory
path = "My Documents"
dirs = os.listdir( path )
# print the files in given directory
for file in dirs:
print (file)
إذا فكرت سأرمي هذا.طريقة بسيطة وقذرة لإجراء عمليات البحث عن أحرف البدل.
import re
import os
[a for a in os.listdir(".") if re.search("^.*\.py$",a)]
سوف يسرد الكود أدناه الدلائل والملفات الموجودة داخل الدليل
def print_directory_contents(sPath):
import os
for sChild in os.listdir(sPath):
sChildPath = os.path.join(sPath,sChild)
if os.path.isdir(sChildPath):
print_directory_contents(sChildPath)
else:
print(sChildPath)
أعلم أن هذا سؤال قديم.هذه طريقة رائعة وجدتها إذا كنت تستخدم جهاز Linux.
import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))
الذي عمل معي هو نوع من نسخة معدلة من إجابة صالح أعلاه.
رمز على النحو التالي:
"dir = 'given_directory_name' filenames = [os.path.abspath(os.path.join(dir,i)) for i in os.listdir(dir)]"
بينما os.listdir()
يعد أمرًا جيدًا لإنشاء قائمة بأسماء الملفات والأسماء، وفي كثير من الأحيان تريد القيام بالمزيد بمجرد حصولك على هذه الأسماء - وفي Python3، com.pathlib يجعل تلك الأعمال الأخرى بسيطة.دعونا نلقي نظرة ونرى ما إذا كنت ترغب في ذلك بقدر ما أفعل.
لسرد محتويات dir، أنشئ كائن مسار وامسك بالمكرِّر:
In [16]: Path('/etc').iterdir()
Out[16]: <generator object Path.iterdir at 0x110853fc0>
إذا أردنا فقط قائمة بأسماء الأشياء:
In [17]: [x.name for x in Path('/etc').iterdir()]
Out[17]:
['emond.d',
'ntp-restrict.conf',
'periodic',
إذا كنت تريد فقط dirs:
In [18]: [x.name for x in Path('/etc').iterdir() if x.is_dir()]
Out[18]:
['emond.d',
'periodic',
'mach_init.d',
إذا كنت تريد أسماء جميع ملفات conf الموجودة في تلك الشجرة:
In [20]: [x.name for x in Path('/etc').glob('**/*.conf')]
Out[20]:
['ntp-restrict.conf',
'dnsextd.conf',
'syslog.conf',
إذا كنت تريد قائمة بملفات conf في الشجرة>= 1K:
In [23]: [x.name for x in Path('/etc').glob('**/*.conf') if x.stat().st_size > 1024]
Out[23]:
['dnsextd.conf',
'pf.conf',
'autofs.conf',
يصبح حل المسارات النسبية أمرًا سهلاً:
In [32]: Path('../Operational Metrics.md').resolve()
Out[32]: PosixPath('/Users/starver/code/xxxx/Operational Metrics.md')
يعد التنقل باستخدام المسار واضحًا جدًا (على الرغم من أنه غير متوقع):
In [10]: p = Path('.')
In [11]: core = p / 'web' / 'core'
In [13]: [x for x in core.iterdir() if x.is_file()]
Out[13]:
[PosixPath('web/core/metrics.py'),
PosixPath('web/core/services.py'),
PosixPath('web/core/querysets.py'),