我想使用tree
(或类似) 查看给定目录的目录结构以及每个子目录中是否有文件。那么,如何使用tree
但限制给定子目录中显示的最大文件数?
如果不能做到这一点tree
,那么如何通过修改 Python 代码来实现本网站?
答案1
这里有一个包含您引用的 Python 代码的工作示例:
用法:tree.py -f [file limit] <directory>
如果为 -f [文件限制] 指定了一个数字,则... <additional files>
打印并跳过其他文件。但是不应跳过其他目录。如果文件限制设置为 10000(默认),则不作为限制
#! /usr/bin/env python
# tree.py
#
# Written by Doug Dahms
# modified by glallen @ StackExchange
#
# 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, limit=10000):
print padding[:-1] + '+-' + basename(abspath(dir)) + '/'
padding = padding + ' '
limit = int(limit)
files = []
if print_files:
files = listdir(dir)
else:
files = [x for x in listdir(dir) if isdir(dir + sep + x)]
count = 0
for file in files:
count += 1
path = dir + sep + file
if isdir(path):
print padding + '|'
if count == len(files):
tree(path, padding + ' ', print_files, limit)
else:
tree(path, padding + '|', print_files, limit)
else:
if limit == 10000:
print padding + '|'
print padding + '+-' + file
continue
elif limit == 0:
print padding + '|'
print padding + '+-' + '... <additional files>'
limit -= 1
elif limit <= 0:
continue
else:
print padding + '|'
print padding + '+-' + file
limit -= 1
def usage():
return '''Usage: %s [-f] [file-listing-limit(int)] <PATH>
Print tree structure of path specified.
Options:
-f Print files as well as directories
-f [limit] Print files as well as directories up to number limit
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, ' ')
else:
print 'ERROR: \'' + path + '\' is not a directory'
elif len(argv) == 3 and argv[1] == '-f':
# print directories and files
path = argv[2]
if isdir(path):
tree(path, ' ', True)
else:
print 'ERROR: \'' + path + '\' is not a directory'
elif len(argv) == 4 and argv[1] == '-f':
# print directories and files up to max
path = argv[3]
if isdir(path):
tree(path, ' ', True, argv[2])
else:
print 'ERROR: \'' + path + '\' is not a directory'
else:
print usage()
if __name__ == '__main__':
main()
运行时,它应该产生类似以下内容的输出:
user@host /usr/share/doc $ python /tmp/recipe-217212-1.py -f 2 . | head -n 40
+-doc/
|
+-libgnuradio-fft3.7.2.1/
| |
| +-copyright
| |
| +-changelog.Debian.gz
|
+-libqt4-script/
| |
| +-LGPL_EXCEPTION.txt
| |
| +-copyright
| |
| +-... <additional files>
|
+-xscreensaver-gl/
| |
| +-copyright
| |
| +-changelog.Debian.gz
| |
| +-... <additional files>
答案2
可以用来tree --filelimit=N
限制显示的子目录/文件的数量。不幸的是,这不会打开包含超过 N 个子目录和文件的目录。
对于简单的情况,当您有多个目录并且大多数目录有太多(例如> 100)文件时,您可以使用tree --filelimit=100
。
.
├── A1
│ ├── A2
│ ├── B2
│ ├── C2 [369 entries exceeds filelimit, not opening dir]
│ └── D2 [3976 entries exceeds filelimit, not opening dir]
├── B1
│ └── A2
│ ├── A3.jpeg
│ └── B3.png
└── C1.sh
笔记,如果A1/C2有子目录A3,则不会显示。
附言这不是一个完整的解决方案,但对于一些人来说会更快。
答案3
更新了上面@glallen 的 Python 3 版本tree.py
。
#!/usr/bin/env python3
# tree.py
#
# Written by Doug Dahms
# modified by glallen @ StackExchange
#
# Prints the tree structure for the path specified on the command line
import os
import sys
def tree(directory, padding, print_files=False, limit=10000):
print(padding[:-1] + '+-' + os.path.basename(os.path.abspath(directory)) + '/')
padding = padding + ' '
limit = int(limit)
files = []
if print_files:
files = os.listdir(directory)
else:
files = [x for x in os.listdir(directory) if os.path.isdir(os.path.join(directory, x))]
count = 0
for file in files:
count += 1
path = os.path.join(directory, file)
if os.path.isdir(path):
print(padding + '|')
if count == len(files):
tree(path, padding + ' ', print_files, limit)
else:
tree(path, padding + '|', print_files, limit)
else:
if limit == 10000:
print(padding + '|')
print(padding + '+-' + file)
continue
elif limit == 0:
print(padding + '|')
print(padding + '+-' + '... <additional files>')
limit -= 1
elif limit <= 0:
continue
else:
print(padding + '|')
print(padding + '+-' + file)
limit -= 1
def usage():
return '''Usage: {} [-f] [file-listing-limit(int)] <PATH>
Print tree structure of path specified.
Options:
-f Print files as well as directories
-f [limit] Print files as well as directories up to number limit
PATH Path to process'''.format(os.path.basename(sys.argv[0]))
def main():
if len(sys.argv) == 1:
print(usage())
elif len(sys.argv) == 2:
# print just directories
path = sys.argv[1]
if os.path.isdir(path):
tree(path, ' ')
else:
print('ERROR: \'' + path + '\' is not a directory')
elif len(sys.argv) == 3 and sys.argv[1] == '-f':
# print directories and files
path = sys.argv[2]
if os.path.isdir(path):
tree(path, ' ', True)
else:
print('ERROR: \'' + path + '\' is not a directory')
elif len(sys.argv) == 4 and sys.argv[1] == '-f':
# print directories and files up to max
path = sys.argv[3]
if os.path.isdir(path):
tree(path, ' ', True, sys.argv[2])
else:
print('ERROR: \'' + path + '\' is not a directory')
else:
print(usage())
if __name__ == '__main__':
main()
答案4
另一种方法可能是过滤提供的 json 输出tree
。例如,tree -J
显示:
[
{"type":"directory","name":"root_directory/","contents":[
{"type":"directory","name":"child_directory","contents":[
{"type":"file","name":"file06.txt"},
{"type":"file","name":"file07.txt"}
]},
{"type":"file","name":"file00.txt"},
{"type":"file","name":"file01.txt"},
{"type":"file","name":"file02.txt"},
{"type":"file","name":"file03.txt"},
{"type":"file","name":"file04.txt"},
{"type":"file","name":"file05.txt"}
]},
{"type":"report","directories":2,"files":8}
]
可以过滤此 json 以截断长文件列表。
import json
def truncate_directories(json_data, max_files):
# Parse JSON data
data = json.loads(json_data)
# Iterate through each item in the JSON data
for item in data:
if item.get('type') == 'directory':
contents = item.get('contents')
if contents and len(contents) > max_files:
# Truncate the contents of the directory
item['contents'] = contents[:3] + [{"type": "file", "name": "..."}] + contents[-3:]
# Convert the modified data back to JSON format
return json.dumps(data, indent=2)
# Example JSON data
json_data = '''
[
{"type":"directory","name":"root_directory/","contents":[
{"type":"directory","name":"child_directory","contents":[
{"type":"file","name":"file06.txt"},
{"type":"file","name":"file07.txt"}
]},
{"type":"file","name":"file00.txt"},
{"type":"file","name":"file01.txt"},
{"type":"file","name":"file02.txt"},
{"type":"file","name":"file03.txt"},
{"type":"file","name":"file04.txt"},
{"type":"file","name":"file05.txt"}
]},
{"type":"report","directories":2,"files":8}
]
'''
# Set the maximum number of files allowed in a directory
max_files = 3
# Truncate directories with too many files
new_json_data = truncate_directories(json_data, max_files)
# Print the modified JSON data
print(new_json_data)
[
{
"type": "directory",
"name": "root_directory/",
"contents": [
{
"type": "directory",
"name": "child_directory",
"contents": [
{"type": "file", "name": "file06.txt"},
{"type": "file", "name": "file07.txt"}
]
},
{"type": "file", "name": "file00.txt"},
{"type": "file", "name": "..."}, # TRUNCATED FILES
{"type": "file", "name": "file05.txt"}
]
},
{"type": "report", "directories": 2, "files": 8}
]
在模拟输出中,“root_directory/”包含六个文件,而不是八个。中间文件“file01.txt”、“file02.txt”、“file03.txt”和“file04.txt”已被替换为 {“type”:“file”、“name”:“...”} 以满足截断标准。
如果此 json 被正确输出(例如,作为路径或制表符缩进的文件),“tree”应该能够显示自定义截断的树数据。
$ tree --help
------- Input options -------
-fromfile Reads paths from files (.=stdin)
--fromtabfile Reads trees from tab indented files (.=stdin)