अजगर में सूची निर्देशिका पेड़ की संरचना?


111

मुझे पता है कि हम os.walk()एक निर्देशिका में सभी उप-निर्देशिका या सभी फाइलों को सूचीबद्ध करने के लिए उपयोग कर सकते हैं । हालाँकि, मैं पूर्ण निर्देशिका ट्री सामग्री को सूचीबद्ध करना चाहूंगा:

- Subdirectory 1:
   - file11
   - file12
   - Sub-sub-directory 11:
         - file111
         - file112
- Subdirectory 2:
    - file21
    - sub-sub-directory 21
    - sub-sub-directory 22    
        - sub-sub-sub-directory 221
            - file 2211

पायथन में इसे कैसे प्राप्त किया जाए?

जवाबों:


146

यहाँ एक प्रारूपण के साथ ऐसा करने का कार्य है:

import os

def list_files(startpath):
    for root, dirs, files in os.walk(startpath):
        level = root.replace(startpath, '').count(os.sep)
        indent = ' ' * 4 * (level)
        print('{}{}/'.format(indent, os.path.basename(root)))
        subindent = ' ' * 4 * (level + 1)
        for f in files:
            print('{}{}'.format(subindent, f))

1
यह बहुत अच्छी तरह से काम किया, धन्यवाद। हालांकि अधिकांश को पता होगा, अभी भी नए लोगों को अजगर में लाभ के लिए - कृपया ध्यान दें कि आपको फ़ंक्शन को अंत में (विंडोज़ मानकर) कॉल करने की आवश्यकता होगी, इसलिए आप अंत में सामग्री list_files ("D:" के साथ एक नई पंक्ति जोड़ सकते हैं) \\ ")
राहुल

1
Python3 पर अच्छी तरह से काम किया। लेकिन अजगर 2 पर ValueError: zero length field name in formatफेंक दिया जाता है।
निपुणसुधा

3
यदि startpath को रूट के भीतर दोहराया जाता है, तो क्या यह प्रत्येक घटना को प्रतिस्थापित नहीं करेगा? बदलने के लिए root.replace(startpath, '', 1)तय करना चाहिए कि
drone.ah

31

उपरोक्त उत्तर के समान, लेकिन python3 के लिए, यकीनन पठनीय और यकीनन एक्स्टेंसिबल:

from pathlib import Path

class DisplayablePath(object):
    display_filename_prefix_middle = '├──'
    display_filename_prefix_last = '└──'
    display_parent_prefix_middle = '    '
    display_parent_prefix_last = '│   '

    def __init__(self, path, parent_path, is_last):
        self.path = Path(str(path))
        self.parent = parent_path
        self.is_last = is_last
        if self.parent:
            self.depth = self.parent.depth + 1
        else:
            self.depth = 0

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    @classmethod
    def make_tree(cls, root, parent=None, is_last=False, criteria=None):
        root = Path(str(root))
        criteria = criteria or cls._default_criteria

        displayable_root = cls(root, parent, is_last)
        yield displayable_root

        children = sorted(list(path
                               for path in root.iterdir()
                               if criteria(path)),
                          key=lambda s: str(s).lower())
        count = 1
        for path in children:
            is_last = count == len(children)
            if path.is_dir():
                yield from cls.make_tree(path,
                                         parent=displayable_root,
                                         is_last=is_last,
                                         criteria=criteria)
            else:
                yield cls(path, displayable_root, is_last)
            count += 1

    @classmethod
    def _default_criteria(cls, path):
        return True

    @property
    def displayname(self):
        if self.path.is_dir():
            return self.path.name + '/'
        return self.path.name

    def displayable(self):
        if self.parent is None:
            return self.displayname

        _filename_prefix = (self.display_filename_prefix_last
                            if self.is_last
                            else self.display_filename_prefix_middle)

        parts = ['{!s} {!s}'.format(_filename_prefix,
                                    self.displayname)]

        parent = self.parent
        while parent and parent.parent is not None:
            parts.append(self.display_parent_prefix_middle
                         if parent.is_last
                         else self.display_parent_prefix_last)
            parent = parent.parent

        return ''.join(reversed(parts))

उदाहरण का उपयोग:

paths = DisplayablePath.make_tree(Path('doc'))
for path in paths:
    print(path.displayable())

उदाहरण आउटपुट:

doc/
├── _static/
   ├── embedded/
      ├── deep_file
      └── very/
          └── deep/
              └── folder/
                  └── very_deep_file
   └── less_deep_file
├── about.rst
├── conf.py
└── index.rst

टिप्पणियाँ

  • यह पुनरावर्तन का उपयोग करता है। यह वास्तव में गहरी पर एक RecursionError को बढ़ाएगा फ़ोल्डर पेड़ों
  • पेड़ का आलसी मूल्यांकन किया जाता है। यह वास्तव में व्यापक फ़ोल्डर पेड़ों पर अच्छा व्यवहार करना चाहिए । किसी दिए गए फ़ोल्डर के तत्काल बच्चों का आलसी मूल्यांकन नहीं किया जाता है, हालांकि।

संपादित करें:

  • जोड़ा गया बोनस! पथ फ़िल्टरिंग के लिए मापदंड कॉलबैक।

अच्छा उपकरण, क्या आपके पास फ़ोल्डर के नामों को बाहर करने के लिए मापदंड का उपयोग करने का एक त्वरित उदाहरण है?
मैट-मैक-मफिन

यही वह है जिसकी तलाश में मैं हूं। आपको बहुत - बहुत धन्यवाद!
ढिंज

24

आपके इंडेंटेशन के बिना एक समाधान:

for path, dirs, files in os.walk(given_path):
  print path
  for f in files:
    print f

os.walk पहले से ही टॉप-डाउन, डेप्थ-फर्स्ट वॉक करता है जिसे आप ढूंढ रहे हैं।

Dirs सूची को अनदेखा करना आपके द्वारा उल्लिखित ओवरलैपिंग को रोकता है।


2
अजगर कहता है:NameError: name 'path' is not defined
फ्रांसेस्को मंतोवानी

1
@FrancescoMantovani "पथ" वह चर है जिसमें वह निर्देशिका है जिसे आप प्रिंट करना चाहते हैं, अर्थात r "C: \ Users \ username \ Documents \ path"
zwelz

16

पाइथन में सूची निर्देशिका वृक्ष संरचना?

हम आमतौर पर सिर्फ जीएनयू के पेड़ का उपयोग करना पसंद करते हैं, लेकिन हमारे पास हमेशा treeहर प्रणाली नहीं होती है, और कभी-कभी पायथन 3 भी उपलब्ध होता है। यहां एक अच्छा जवाब आसानी से कॉपी-पेस्ट किया जा सकता है और जीएनयू को treeएक आवश्यकता नहीं बना सकता है ।

treeउत्पादन इस तरह दिखता है:

$ tree
.
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

मैंने अपनी निर्देशिका में उपरोक्त निर्देशिका संरचना को एक निर्देशिका कॉल के तहत बनाया है pyscratch

मैं यहाँ अन्य उत्तरों को भी देखता हूँ जो उस प्रकार के आउटपुट को प्राप्त करते हैं, लेकिन मुझे लगता है कि हम सरल, अधिक आधुनिक कोड और आलसियों के मूल्यांकन के तरीकों से बेहतर कर सकते हैं।

अजगर में पेड़

शुरुआत करने के लिए, आइए एक उदाहरण का उपयोग करें

  • पायथन 3 का उपयोग करता है Path ऑब्जेक्ट
  • yieldऔर का उपयोग करता हैyield from अभिव्यक्ति (जो एक जनरेटर फ़ंक्शन बनाता है)
  • सुरुचिपूर्ण सादगी के लिए पुनरावर्तन का उपयोग करता है
  • अतिरिक्त स्पष्टता के लिए टिप्पणियों और कुछ प्रकार के एनोटेशन का उपयोग करता है
from pathlib import Path

# prefix components:
space =  '    '
branch = '│   '
# pointers:
tee =    '├── '
last =   '└── '


def tree(dir_path: Path, prefix: str=''):
    """A recursive generator, given a directory Path object
    will yield a visual tree structure line by line
    with each line prefixed by the same characters
    """    
    contents = list(dir_path.iterdir())
    # contents each get pointers that are ├── with a final └── :
    pointers = [tee] * (len(contents) - 1) + [last]
    for pointer, path in zip(pointers, contents):
        yield prefix + pointer + path.name
        if path.is_dir(): # extend the prefix and recurse:
            extension = branch if pointer == tee else space 
            # i.e. space because last, └── , above so no more |
            yield from tree(path, prefix=prefix+extension)

और अब:

for line in tree(Path.home() / 'pyscratch'):
    print(line)

प्रिंट:

├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

हमें प्रत्येक निर्देशिका को सूची में शामिल करने की आवश्यकता है क्योंकि हमें यह जानने की आवश्यकता है कि यह कितना लंबा है, लेकिन बाद में हम सूची को फेंक देते हैं। गहरी और व्यापक पुनरावृत्ति के लिए यह पर्याप्त आलसी होना चाहिए।

उपरोक्त कोड, टिप्पणियों के साथ, यह पूरी तरह से समझने के लिए पर्याप्त होना चाहिए कि हम यहाँ क्या कर रहे हैं, लेकिन बेझिझक एक डिबगर के माध्यम से इसके माध्यम से कदम उठाने के लिए स्वतंत्र महसूस करें यदि आपको इसकी आवश्यकता है।

अधिक सुविधाएं

अब GNU treeहमें कुछ उपयोगी सुविधाएँ प्रदान करता है जिन्हें मैं इस फ़ंक्शन के साथ रखना चाहता हूँ:

  • विषय निर्देशिका नाम को पहले प्रिंट करता है (स्वचालित रूप से, हमारा नहीं है)
  • की गिनती छापता है n directories, m files
  • प्रत्यावर्तन को सीमित करने का विकल्प, -L level
  • विकल्प सिर्फ निर्देशिका तक सीमित करने के लिए, -d

इसके अलावा, जब कोई विशाल पेड़ होता है, तो isliceपाठ के साथ अपने दुभाषिया को लॉक करने से बचने के लिए पुनरावृत्ति (जैसे के साथ ) को सीमित करना उपयोगी होता है , क्योंकि कुछ बिंदु पर आउटपुट उपयोगी होने के लिए बहुत अधिक क्रिया हो जाता है। हम इसे डिफ़ॉल्ट रूप से उच्चतर बना सकते हैं - कह सकते हैं 1000

तो चलो पिछली टिप्पणियों को हटा दें और इस कार्यक्षमता को भरें:

from pathlib import Path
from itertools import islice

space =  '    '
branch = '│   '
tee =    '├── '
last =   '└── '
def tree(dir_path: Path, level: int=-1, limit_to_directories: bool=False,
         length_limit: int=1000):
    """Given a directory Path object print a visual tree structure"""
    dir_path = Path(dir_path) # accept string coerceable to Path
    files = 0
    directories = 0
    def inner(dir_path: Path, prefix: str='', level=-1):
        nonlocal files, directories
        if not level: 
            return # 0, stop iterating
        if limit_to_directories:
            contents = [d for d in dir_path.iterdir() if d.is_dir()]
        else: 
            contents = list(dir_path.iterdir())
        pointers = [tee] * (len(contents) - 1) + [last]
        for pointer, path in zip(pointers, contents):
            if path.is_dir():
                yield prefix + pointer + path.name
                directories += 1
                extension = branch if pointer == tee else space 
                yield from inner(path, prefix=prefix+extension, level=level-1)
            elif not limit_to_directories:
                yield prefix + pointer + path.name
                files += 1
    print(dir_path.name)
    iterator = inner(dir_path, level=level)
    for line in islice(iterator, length_limit):
        print(line)
    if next(iterator, None):
        print(f'... length_limit, {length_limit}, reached, counted:')
    print(f'\n{directories} directories' + (f', {files} files' if files else ''))

और अब हम उसी प्रकार का आउटपुट प्राप्त कर सकते हैं जैसे tree:

tree(Path.home() / 'pyscratch')

प्रिंट:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
      ├── __init__.py
      ├── __main__.py
      └── module.py
   └── subpackage2
       ├── __init__.py
       ├── __main__.py
       └── module2.py
└── package2
    └── __init__.py

4 directories, 9 files

और हम स्तरों तक सीमित कर सकते हैं:

tree(Path.home() / 'pyscratch', level=2)

प्रिंट:

pyscratch
├── package
   ├── __init__.py
   ├── __main__.py
   ├── subpackage
   └── subpackage2
└── package2
    └── __init__.py

4 directories, 3 files

और हम आउटपुट को डायरेक्टरी में सीमित कर सकते हैं:

tree(Path.home() / 'pyscratch', level=2, limit_to_directories=True)

प्रिंट:

pyscratch
├── package
   ├── subpackage
   └── subpackage2
└── package2

4 directories

पूर्वप्रभावी

पूर्वव्यापी में, हम path.globमिलान के लिए उपयोग कर सकते थे । हम शायद path.rglobपुनरावर्ती ग्लोबिंग के लिए भी उपयोग कर सकते हैं , लेकिन इसके लिए फिर से लिखना होगा। हम भी इस्तेमाल कर सकते हैंitertools.tee निर्देशिका सामग्री की एक सूची को भौतिक बजाय हैं, लेकिन इससे नकारात्मक ट्रेडऑफ़ हो सकते हैं और संभवतः कोड को और भी अधिक जटिल बना देगा।

टिप्पणियों का स्वागत है!


elif not limit_to_directories:निम्नलिखित को जोड़ने के बाद, लाइनों की कोड को भी प्रिंट करें : उचित सफेद स्थान के लिए इस लिंक को info = prefix + pointer + path.name; try: with path.open('r') as f: n_lines = len(f.readlines()); loc = f' LOC: {n_lines}'; info += loc; except UnicodeDecodeError: pass; yield info देखें ।
स्टीवन सी। हॉवेल

यह वही था जो मुझे अपने कोड में चाहिए था, और मुझे कुछ नए पायथन ट्रिक्स सिखाए! केवल एक चीज जो मैं नोट कर रहा हूं वह यह है कि contentsअगर limit_to_directoriesसच है तो फ़िल्टर किया जाना चाहिए । अन्यथा यदि किसी फ़ोल्डर में अंतिम फ़ाइल के लिए कोई निर्देशिका नहीं है, तो पेड़ सही तरीके से नहीं खींचा जाएगा। if limit_to_directories: contents = [path for path in contents if path.is_dir()]
hennign

@ धन्यवाद धन्यवाद, जवाब अपडेट किया गया, प्रतिक्रिया की सराहना करें!
हारून हॉल

पायथन list(dir_path.iterdir())निर्देशिका संरचना के एक ठीक से क्रमबद्ध टॉप-डाउन ट्री को वापस करने पर सभी समर्पित है । मैं iterdir () के लिए एपीआई में ऐसी कोई गारंटी नहीं देखता हूं । कृपया वांछित ऑर्डर प्रदान करने के लिए ऑर्डर या गारंटी के बारे में एक संदर्भ प्रदान करें। iterdir()
ingyhere

@ मैं यह सुनिश्चित नहीं कर रहा हूं कि आपको वह विचार कहां मिला है - यह डिफ़ॉल्ट रूप से उपयोग करने के लिए लगता हैos.listdir() - जो आदेश की कोई गारंटी नहीं देता है : "सूची मनमाने क्रम में है, और विशेष प्रविष्टियों को शामिल नहीं करता है। '' और '..' भले ही वे निर्देशिका में मौजूद हों। "
हारून हॉल

15

मैं यहां उसी चीज की तलाश में आया था और मेरे लिए धोबों के जवाब का इस्तेमाल करता था। समुदाय को धन्यवाद देने के एक तरीके के रूप में, मैंने एक फ़ाइल में लिखने के लिए कुछ तर्क जोड़े, जैसा कि अक्षय ने पूछा, और फाइलों को वैकल्पिक बनाते हुए दिखाया, इसलिए यह इतना आउटपुट नहीं है। इसके अलावा इंडेंटेशन को एक वैकल्पिक तर्क बनाया ताकि आप इसे बदल सकें, क्योंकि कुछ इसे 2 और अन्य 4 पसंद करते हैं।

अलग-अलग छोरों का उपयोग किया जाता है ताकि एक फाइल दिखाई न दे, अगर यह प्रत्येक पुनरावृत्ति पर है।

आशा है कि यह किसी और की मदद करता है क्योंकि dhobbs उत्तर ने मेरी मदद की। बहुत बहुत धन्यवाद।

def showFolderTree(path,show_files=False,indentation=2,file_output=False):
"""
Shows the content of a folder in a tree structure.
path -(string)- path of the root folder we want to show.
show_files -(boolean)-  Whether or not we want to see files listed.
                        Defaults to False.
indentation -(int)- Indentation we want to use, defaults to 2.   
file_output -(string)-  Path (including the name) of the file where we want
                        to save the tree.
"""


tree = []

if not show_files:
    for root, dirs, files in os.walk(path):
        level = root.replace(path, '').count(os.sep)
        indent = ' '*indentation*(level)
        tree.append('{}{}/'.format(indent,os.path.basename(root)))

if show_files:
    for root, dirs, files in os.walk(path):
        level = root.replace(path, '').count(os.sep)
        indent = ' '*indentation*(level)
        tree.append('{}{}/'.format(indent,os.path.basename(root)))    
        for f in files:
            subindent=' ' * indentation * (level+1)
            tree.append('{}{}'.format(subindent,f))

if file_output:
    output_file = open(file_output,'w')
    for line in tree:
        output_file.write(line)
        output_file.write('\n')
else:
    # Default behaviour: print on screen.
    for line in tree:
        print line

मुझे लगता है कि यह उत्तर पहले से स्वीकृत उत्तर में योगदान नहीं करता है। केवल एक चीज जो आप प्रदान कर रहे हैं, प्रतिक्रिया में सुविधाओं को बंद करने या न करने के लिए अतिरिक्त फ़्लफ़ कोड है।
कोडलाइकबीर

3
आपकी भावना सही है, @ जेसन-हेइन। स्वीकृत उत्तर काफी अच्छा है, लेकिन कुछ लोगों ने पूछा कि यह फुलाना कैसे करना है और मैं उन्हें कुछ देना चाहता था। इसे डाउनवोट करें या मेरे उत्तर की रिपोर्ट करें यदि आप इसे एसओ में नहीं देखना चाहते हैं, तो मुझे लगा कि यह चोट नहीं पहुंचाएगा, लेकिन मैं गलत हो सकता हूं।
रूबेन काबेरा

3
यह वास्तव में उपयोगी है। बहुत बहुत धन्यवाद। मैंने इसे वैसे ही इस्तेमाल किया।
vladblindu

7

इस शानदार पोस्ट के आधार पर

http://code.activestate.com/recipes/217212-treepy-graphically-displays-the-directory-structur/

यहाँ बिल्कुल वैसा ही व्यवहार करने के लिए परिशोधन किया जाता है

http://linux.die.net/man/1/tree

#! / usr / bin / env python2 # - * - कोडिंग: utf-8 - * -


# Tree.py # # डौग डैम द्वारा लिखित # # कमांड लाइन पर निर्दिष्ट पथ के लिए ट्री संरचना को प्रिंट करता है





से ओएस आयात listdir , सितम्बर
 से ओएस पथ आयात abspath , basename , isdir
 से sys आयात argv

डीईएफ़ पेड़ ( dir , गद्दी , print_files = झूठी , isLast = झूठी , isFirst = झूठी ): यदि isFirst : प्रिंट गद्दी डीकोड ( 'utf8' ) [: - 1 ]। एनकोड ( 'UTF8' )
    
          + dir
     बाकी : अगर isLast : प्रिंट गद्दी डीकोड ( 'utf8' ) [: - 1 एनकोड
        
             ]।( 'UTF8' ) + '└──' + basename ( abspath ( dir )) बाकी : प्रिंट गद्दी डीकोड ( 'utf8' ) [: - 1 ]। सांकेतिक शब्दों में बदलना ( 'utf8' ) + ' + ' + basename ( abspath ( dir )) 
    फाइलें = [] अगर Print_files : 
        files = listdir ( dir ) और 
        फाइलें   
        
                
    
     : = [ एक्स के लिए एक्स में listdir ( dir ) यदि isdir ( dir + सितम्बर + x )] अगर नहीं isFirst : 
        गद्दी = गद्दी + '' 
    फ़ाइलों = अनुसार क्रमबद्ध ( , कुंजी = लैम्ब्डा रों : रों कम ()) 
    गिनती = 0 
    अंतिम = लेन (  
       फ़ाइलें फ़ाइलें ) - 1 के लिए , मैं गणना में फ़ाइल ( फ़ाइलें ): 
        गिनती + = 1 
        पथ = dir + sep + फ़ाइल  
     
        isLast = मैं == पिछले
         यदि isdir ( पथ ): यदि गिनती == लेन ( फ़ाइलें ): यदि isFirst : 
                    पेड़ ( पथ , गद्दी , print_files , isLast , झूठी ) बाकी : 
                    पेड़ ( पथ , गद्दी + '' , print_files , isLast , गलत )
            
                 
                  
             बाकी : 
                पेड़ ( पथ , गद्दी + '│' , print_files , isLast ,  False)
        else:
            if isLast:
                print padding + '└── ' + file
            else:
                print padding + '├── ' + file

def usage():
    return '''Usage: %s [-f] 
Print tree structure of path specified.
Options:
-f      Print files as well as directories
PATH    Path to process''' % basename(argv[0])

def main():
    if len(argv) == 1:
        print usage()
    elif len(argv) == 2:
        # print just directories
        path = argv[1]
        if isdir(path):
            tree(path, '', False, False, True)
        else:
            print 'ERROR: \'' + path + '\' is not a directory'
    elif len(argv) == 3 और argv [ 1 ] == -f ' : # प्रिंट निर्देशिका और फ़ाइलें 
        पथ = argv [ 2 ] यदि isdir ( पथ ): 
            वृक्ष ( पथ , ' ' , सत्य , गलत , सच्चा)     
        
            )
        else:
            print 'ERROR: \'' + path + '\' एक निर्देशिका 'नहीं है और कुछ : प्रिंट उपयोग ()
    
        

अगर __name__ == '__main__' : 
    मुख्य () 


6
import os

def fs_tree_to_dict(path_):
    file_token = ''
    for root, dirs, files in os.walk(path_):
        tree = {d: fs_tree_to_dict(os.path.join(root, d)) for d in dirs}
        tree.update({f: file_token for f in files})
        return tree  # note we discontinue iteration trough os.walk

अगर किसी को दिलचस्पी है - वह पुनरावर्ती फ़ंक्शन शब्दकोशों की नेस्टेड संरचना लौटाता है। कुंजी file systemनाम (निर्देशिका और फ़ाइलों के) हैं, मान या तो हैं:

  • निर्देशिका के लिए उप शब्दकोश
  • फ़ाइलों के लिए तार (देखें file_token)

इस उदाहरण में स्ट्रिंगिंग पदनाम फाइलें खाली हैं। वे भी उदाहरण के लिए फ़ाइल सामग्री या उसके मालिक की जानकारी या विशेषाधिकार या जो कुछ भी एक तानाशाही से भिन्न हो सकते हैं। जब तक यह एक शब्दकोश नहीं है, इसे आसानी से आगे के संचालन में "निर्देशिका प्रकार" से अलग किया जा सकता है।

फाइलसिस्टम में ऐसा पेड़ होना:

# bash:
$ tree /tmp/ex
/tmp/ex
├── d_a
   ├── d_a_a
   ├── d_a_b
      └── f1.txt
   ├── d_a_c
   └── fa.txt
├── d_b
   ├── fb1.txt
   └── fb2.txt
└── d_c

परिणाम होगा:

# python 2 or 3:
>>> fs_tree_to_dict("/tmp/ex")
{
    'd_a': {
        'd_a_a': {},
        'd_a_b': {
            'f1.txt': ''
        },
        'd_a_c': {},
        'fa.txt': ''
    },
    'd_b': {
        'fb1.txt': '',
        'fb2.txt': ''
    },
    'd_c': {}
}

यदि आप इसे पसंद करते हैं, तो मैंने पहले ही इस सामान (और एक अच्छा pyfakefsसहायक) के साथ एक पैकेज (अजगर 2 और 3) बनाया है : https://pypi.org/project/fsforge/


4

ऊपर दिए गए dobobbs के उत्तर में ( https://stackoverflow.com/a/9728478/624597 ), यहाँ एक फ़ाइल के लिए परिणाम जमा करने की एक अतिरिक्त कार्यक्षमता है (मैं व्यक्तिगत रूप से इसका उपयोग कॉपी और पेस्ट करने के लिए फ्रीमाइंड का एक अच्छा अवलोकन करने के लिए करता हूँ। संरचना, इसलिए मैंने इंडेंटेशन के लिए रिक्त स्थान के बजाय टैब का उपयोग किया):

import os

def list_files(startpath):

    with open("folder_structure.txt", "w") as f_output:
        for root, dirs, files in os.walk(startpath):
            level = root.replace(startpath, '').count(os.sep)
            indent = '\t' * 1 * (level)
            output_string = '{}{}/'.format(indent, os.path.basename(root))
            print(output_string)
            f_output.write(output_string + '\n')
            subindent = '\t' * 1 * (level + 1)
            for f in files:
                output_string = '{}{}'.format(subindent, f)
                print(output_string)
                f_output.write(output_string + '\n')

list_files(".")

इस उत्तर ने वास्तव में मदद की, धन्यवाद
प्रीक्स

2

आप लिनक्स शेल के 'ट्री' कमांड को निष्पादित कर सकते हैं।

स्थापना:

   ~$sudo apt install tree

अजगर में उपयोग करना

    >>> import os
    >>> os.system('tree <desired path>')

उदाहरण:

    >>> os.system('tree ~/Desktop/myproject')

यह आपको एक क्लीनर संरचना देता है और नेत्रहीन अधिक व्यापक और टाइप करने में आसान है।


यह बहुत पोर्टेबल समाधान नहीं है क्योंकि यह विंडोज पर विफल रहता है + अतिरिक्त कार्यक्रम पर निर्भर करता है
ओग्लोप

2

यह समाधान केवल तभी काम करेगा जब आपने treeअपने सिस्टम पर स्थापित किया है। हालाँकि मैं इस समाधान को यहाँ छोड़ रहा हूँ जब यह किसी और को बाहर निकालने में मदद करता है।

आप ट्री स्ट्रक्चर को ट्री स्ट्रक्चर को XML ( tree -X) या JSON ( tree -J) के रूप में आउटपुट करने के लिए कह सकते हैं । JSON के पाठ्यक्रम को सीधे अजगर के साथ पार्स किया जा सकता है और XML को आसानी से पढ़ा जा सकता है lxml

एक उदाहरण के रूप में निम्नलिखित निर्देशिका संरचना के साथ:

[sri@localhost Projects]$ tree --charset=ascii bands
bands
|-- DreamTroll
|   |-- MattBaldwinson
|   |-- members.txt
|   |-- PaulCarter
|   |-- SimonBlakelock
|   `-- Rob Stringer
|-- KingsX
|   |-- DougPinnick
|   |-- JerryGaskill
|   |-- members.txt
|   `-- TyTabor
|-- Megadeth
|   |-- DaveMustaine
|   |-- DavidEllefson
|   |-- DirkVerbeuren
|   |-- KikoLoureiro
|   `-- members.txt
|-- Nightwish
|   |-- EmppuVuorinen
|   |-- FloorJansen
|   |-- JukkaNevalainen
|   |-- MarcoHietala
|   |-- members.txt
|   |-- TroyDonockley
|   `-- TuomasHolopainen
`-- Rush
    |-- AlexLifeson
    |-- GeddyLee
    `-- NeilPeart

5 directories, 25 files

एक्सएमएल

<?xml version="1.0" encoding="UTF-8"?>
<tree>
  <directory name="bands">
    <directory name="DreamTroll">
      <file name="MattBaldwinson"></file>
      <file name="members.txt"></file>
      <file name="PaulCarter"></file>
      <file name="RobStringer"></file>
      <file name="SimonBlakelock"></file>
    </directory>
    <directory name="KingsX">
      <file name="DougPinnick"></file>
      <file name="JerryGaskill"></file>
      <file name="members.txt"></file>
      <file name="TyTabor"></file>
    </directory>
    <directory name="Megadeth">
      <file name="DaveMustaine"></file>
      <file name="DavidEllefson"></file>
      <file name="DirkVerbeuren"></file>
      <file name="KikoLoureiro"></file>
      <file name="members.txt"></file>
    </directory>
    <directory name="Nightwish">
      <file name="EmppuVuorinen"></file>
      <file name="FloorJansen"></file>
      <file name="JukkaNevalainen"></file>
      <file name="MarcoHietala"></file>
      <file name="members.txt"></file>
      <file name="TroyDonockley"></file>
      <file name="TuomasHolopainen"></file>
    </directory>
    <directory name="Rush">
      <file name="AlexLifeson"></file>
      <file name="GeddyLee"></file>
      <file name="NeilPeart"></file>
    </directory>
  </directory>
  <report>
    <directories>5</directories>
    <files>25</files>
  </report>
</tree>

JSON

[sri@localhost Projects]$ tree -J bands
[
  {"type":"directory","name":"bands","contents":[
    {"type":"directory","name":"DreamTroll","contents":[
      {"type":"file","name":"MattBaldwinson"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"PaulCarter"},
      {"type":"file","name":"RobStringer"},
      {"type":"file","name":"SimonBlakelock"}
    ]},
    {"type":"directory","name":"KingsX","contents":[
      {"type":"file","name":"DougPinnick"},
      {"type":"file","name":"JerryGaskill"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TyTabor"}
    ]},
    {"type":"directory","name":"Megadeth","contents":[
      {"type":"file","name":"DaveMustaine"},
      {"type":"file","name":"DavidEllefson"},
      {"type":"file","name":"DirkVerbeuren"},
      {"type":"file","name":"KikoLoureiro"},
      {"type":"file","name":"members.txt"}
    ]},
    {"type":"directory","name":"Nightwish","contents":[
      {"type":"file","name":"EmppuVuorinen"},
      {"type":"file","name":"FloorJansen"},
      {"type":"file","name":"JukkaNevalainen"},
      {"type":"file","name":"MarcoHietala"},
      {"type":"file","name":"members.txt"},
      {"type":"file","name":"TroyDonockley"},
      {"type":"file","name":"TuomasHolopainen"}
    ]},
    {"type":"directory","name":"Rush","contents":[
      {"type":"file","name":"AlexLifeson"},
      {"type":"file","name":"GeddyLee"},
      {"type":"file","name":"NeilPeart"}
    ]}
  ]},
  {"type":"report","directories":5,"files":25}
]

1

शायद @ellockie से अधिक तेज़ (हो सकता है)

आयात os
def file_writer (पाठ):
    खुले रूप में ("folder_structure.txt", "a") f_output के रूप में:
        f_output.write (पाठ)
def_files (startpath):


    रूट के लिए, dirs, फाइलें os.walk (startpath) में:
        स्तर = root.replace (startpath, '') .count (os.sep)
        इंडेंट = '\ t' * 1 * (स्तर)
        output_string = '{} {} / \ n'format (इंडेंट, os.path.basename (रूट))
        file_writer (output_string)
        उपखंड = '\ t' * 1 * (स्तर + 1)
        output_string = '% s% s \ n'% (उपखंड, [फ़ाइलों में f के लिए]]
        file_writer ( ''। में शामिल होने के (output_string))


list_files ( "/")

नीचे स्क्रीनशॉट में परीक्षा परिणाम:

यहां छवि विवरण दर्ज करें



0

उन लोगों के लिए जो अभी भी एक उत्तर की तलाश में हैं। यहाँ एक शब्दकोश में पथ प्राप्त करने के लिए एक पुनरावर्ती दृष्टिकोण है।

import os


def list_files(startpath):
    for root, dirs, files in os.walk(startpath):
        dir_content = []
        for dir in dirs:
            go_inside = os.path.join(startpath, dir)
            dir_content.append(list_files(go_inside))
        files_lst = []
        for f in files:
            files_lst.append(f)
        return {'name': root, 'files': files_lst, 'dirs': dir_content}

0

@ धोबों का जवाब शानदार है!

लेकिन आसानी से स्तर की जानकारी प्राप्त करने के लिए बदल जाते हैं

def print_list_dir(dir):
    print("=" * 64)
    print("[PRINT LIST DIR] %s" % dir)
    print("=" * 64)
    for root, dirs, files in os.walk(dir):
        level = root.replace(dir, '').count(os.sep)
        indent = '| ' * level
        print('{}{} \\'.format(indent, os.path.basename(root)))
        subindent = '| ' * (level + 1)
        for f in files:
            print('{}{}'.format(subindent, f))
    print("=" * 64)

और आउटपुट की तरह

================================================================
[PRINT LIST DIR] ./
================================================================
 \
| os_name.py
| json_loads.py
| linspace_python.py
| list_file.py
| to_gson_format.py
| type_convert_test.py
| in_and_replace_test.py
| online_log.py
| padding_and_clipping.py
| str_tuple.py
| set_test.py
| script_name.py
| word_count.py
| get14.py
| np_test2.py
================================================================

आप |गिनती से स्तर प्राप्त कर सकते हैं !

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.