파이썬에서 디렉토리 트리 구조를 나열합니까?
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
파이썬에서 이것을 가장 잘 달성하는 방법은 무엇입니까?
다음은 서식을 지정하는 기능입니다.
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))
들여 쓰기가없는 솔루션 :
for path, dirs, files in os.walk(given_path):
print path
for f in files:
print f
os.walk는 이미 찾고있는 하향식 깊이 우선 걷기를 수행합니다.
dirs 목록을 무시하면 겹치는 것을 방지 할 수 있습니다.
나는 똑같은 것을 찾고 여기에 와서 나를 위해 dhobbs 대답을 사용했습니다. 커뮤니티에 감사를 표하는 방법으로, akshay가 요청한대로 파일에 쓰기위한 몇 가지 인수를 추가하고 파일 표시를 선택 사항으로 설정하여 출력이 그렇게 작지 않게했습니다. 또한 일부는 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
위의 답변과 유사하지만 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 가 발생 합니다.
- 나무는 느리게 평가됩니다. 정말 넓은 폴더 트리 에서 잘 작동해야합니다 . 그러나 주어진 폴더의 직계 자식은 느리게 평가되지 않습니다.
편집하다:
- 보너스 추가! 필터링 경로에 대한 기준 콜백.
이 환상적인 게시물을 기반으로
http://code.activestate.com/recipes/217212-treepy-graphically-displays-the-directory-structur/
여기에 정확히 다음과 같이 작동하는 개선이 있습니다.
http://linux.die.net/man/1/tree
#!/usr/bin/env python2 # -*- coding: utf-8 -*- # tree.py # # Written by Doug Dahms # # Prints the tree structure for the path specified on the command line from os import listdir, sep from os.path import abspath, basename, isdir from sys import argv def tree(dir, padding, print_files=False, isLast=False, isFirst=False): if isFirst: print padding.decode('utf8')[:-1].encode('utf8') + dir else: if isLast: print padding.decode('utf8')[:-1].encode('utf8') + '└── ' + basename(abspath(dir)) else: print padding.decode('utf8')[:-1].encode('utf8') + '├── ' + basename(abspath(dir)) files = [] if print_files: files = listdir(dir) else: files = [x for x in listdir(dir) if isdir(dir + sep + x)] if not isFirst: padding = padding + ' ' files = sorted(files, key=lambda s: s.lower()) count = 0 last = len(files) - 1 for i, file in enumerate(files): count += 1 path = dir + sep + file isLast = i == last if isdir(path): if count == len(files): if isFirst: tree(path, padding, print_files, isLast, False) else: tree(path, padding + ' ', print_files, isLast, False) else: tree(path, padding + '│', 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 파일 및 디렉토리 인쇄 프로세스 경로 '' '% basename (argv [0]) def main () : len (argv) == 1 : 인쇄 사용 () elif len (argv) == 2 : # 디렉토리 만 인쇄 경로 = argv [1] isdir (경로) : 트리 (경로, '', False, False, True) 그밖에: print '오류 : \'+ 경로 + '\'는 디렉토리가 아닙니다. ' elif len (argv) == 3 및 argv [1] == '-f': # 인쇄 디렉토리 및 파일 경로 = argv [2] isdir (경로) : 트리 (경로, '', True, False, True) 그밖에: print '오류 : \'+ 경로 + '\'는 디렉토리가 아닙니다. ' 그밖에: 인쇄 사용 () __name__ == '__main__'인 경우 : 본관()
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
)
이 예에서는 파일을 지정하는 문자열이 비어 있습니다. 예를 들어 주어진 파일 내용이나 소유자 정보 또는 권한 또는 dict와 다른 객체 일 수도 있습니다. 사전이 아니면 추가 작업에서 "디렉토리 유형"과 쉽게 구별 할 수 있습니다.
파일 시스템에 이러한 트리가있는 경우 :
# 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/
위의 dhobbs 답변 ( https://stackoverflow.com/a/9728478/624597 ) 위에 결과를 파일에 저장하는 추가 기능이 있습니다 (개인적으로 FreeMind 에 복사하여 붙여 넣는 데 사용 하여 멋진 개요를 볼 수 있습니다. 따라서 들여 쓰기를 위해 공백 대신 탭을 사용했습니다.)
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(".")
Linux 쉘의 '트리'명령을 실행할 수 있습니다.
설치:
~$sudo apt install tree
파이썬에서 사용
>>> import os
>>> os.system('tree <desired path>')
예:
>>> os.system('tree ~/Desktop/myproject')
이것은 더 깔끔한 구조를 제공하고 시각적으로 더 포괄적이고 입력하기 쉽습니다.
@ellockie보다 빠를 수도 있습니다 (아마도)
수입 OS def file_writer (텍스트) : open ( "folder_structure.txt", "a")를 f_output으로 사용 : f_output.write (텍스트) def list_files (startpath) : root, dirs, os.walk (startpath)의 파일 : 레벨 = root.replace (startpath, '') .count (os.sep) 들여 쓰기 = '\ t'* 1 * (레벨) output_string = '{} {} / \ n'.format (indent, os.path.basename (root)) 파일 _ 작성기 (출력 _ 문자열) subindent = '\ t'* 1 * (레벨 + 1) output_string = '% s % s \ n'% (subindent, [f for f in files]) file_writer ( ''. join (출력 _ 문자열)) 목록 _ 파일 ( "/")
아래 스크린 샷의 테스트 결과 :
이 솔루션은 tree
시스템에 설치 한 경우에만 작동합니다 . 그러나 다른 사람을 도울 경우를 대비 하여이 솔루션을 여기에 남겨 둡니다.
트리 구조를 XML ( tree -X
) 또는 JSON ( tree -J
) 으로 출력하도록 tree에 지시 할 수 있습니다 . 물론 JSON은 Python으로 직접 구문 분석 할 수 있으며 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
<?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}
]
다음과 같은 출력이있는 코드를 찾을 수 있습니다. https://stackoverflow.com/a/56622847/6671330
V .
|-> V folder1
| |-> V folder2
| | |-> V folder3
| | | |-> file3.txt
| | |-> file2.txt
| |-> V folderX
| |-> file1.txt
|-> 02-hw1_wdwwfm.py
|-> 06-t1-home1.py
|-> 06-t1-home2.py
|-> hw1.py
여전히 답을 찾고있는 사람들을 위해. 다음은 사전에서 경로를 가져 오는 재귀 적 접근 방식입니다.
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}
참고 URL : https://stackoverflow.com/questions/9727673/list-directory-tree-structure-in-python
'Development Tip' 카테고리의 다른 글
명령 줄 인터페이스로 Clojure 앱을 구축하고 계십니까? (0) | 2020.10.11 |
---|---|
메서드의 소스 코드를 어떻게 동적으로 가져올 수 있으며이 메서드가 어떤 파일에 있는지 (0) | 2020.10.11 |
WPF에서 Button MouseOver의 배경을 어떻게 변경합니까? (0) | 2020.10.11 |
Resharper를 사용한 맞춤 중괄호 서식 (0) | 2020.10.11 |
(function () {}) () 구조는 어떻게 작동하며 사람들이 왜 그것을 사용합니까? (0) | 2020.10.11 |