给定输入:
apple: banana eggplant
banana: cantaloupe durian
eggplant:
fig:
我想将其连接成以下格式:
├─ apple
│ ├─ banana
│ │ ├─ cantaloupe
│ │ └─ durian
│ └─ eggplant
└─ fig
可能有也可能没有多个根元素(在上面的示例中,有两个根元素),我想找到一个可以毫无问题地处理它们的解决方案。
是否有任何命令行工具可以处理这种转换?失败了,其他脚本语言中是否有任何东西可以稍微轻松地解决这一问题(我已经看过Python的
pprint
了,但我也不知道如何将其用于类似的事情)? 最佳答案
以下代码将产生您要求的树结构:
branch = '├'
pipe = '|'
end = '└'
dash = '─'
class Tree(object):
def __init__(self, tag):
self.tag = tag
class Node(Tree):
def __init__(self, tag, *nodes):
super(Node, self).__init__(tag)
self.nodes = list(nodes)
class Leaf(Tree):
pass
def _draw_tree(tree, level, last=False, sup=[]):
def update(left, i):
if i < len(left):
left[i] = ' '
return left
print ''.join(reduce(update, sup, ['{} '.format(pipe)] * level)) \
+ (end if last else branch) + '{} '.format(dash) \
+ str(tree.tag)
if isinstance(tree, Node):
level += 1
for node in tree.nodes[:-1]:
_draw_tree(node, level, sup=sup)
_draw_tree(tree.nodes[-1], level, True, [level] + sup)
def draw_tree(trees):
for tree in trees[:-1]:
_draw_tree(tree, 0)
_draw_tree(trees[-1], 0, True, [0])
它要求您使用给定的形式表示数据。
关于数据反序列化,您只需要跟踪父节点,以便当叶子看起来像是一个节点时,只需替换它即可:
class Track(object):
def __init__(self, parent, idx):
self.parent, self.idx = parent, idx
def parser(text):
trees = []
tracks = {}
for line in text.splitlines():
line = line.strip()
key, value = map(lambda s: s.strip(), line.split(':', 1))
nodes = value.split()
if len(nodes):
parent = Node(key)
for i, node in enumerate(nodes):
tracks[node] = Track(parent, i)
parent.nodes.append(Leaf(node))
curnode = parent
if curnode.tag in tracks:
t = tracks[curnode.tag]
t.parent.nodes[t.idx] = curnode
else:
trees.append(curnode)
else:
curnode = Leaf(key)
if curnode.tag in tracks:
# well, how you want to handle it?
pass # ignore
else:
trees.append(curnode)
return trees
它运行:
>>> text='''apple: banana eggplant
banana: cantaloupe durian
eggplant:
fig:'''
>>> draw_tree(parser(text))
├─ apple
| ├─ banana
| | ├─ cantaloupe
| | └─ durian
| └─ eggplant
└─ fig
希望它能完全解决您的问题。
更新
我的代码对一些极端情况提供了一些关注,例如:
>>> text='''apple: banana eggplant
banana: cantaloupe durian
eggplant:'''
>>> draw_tree(parser(text))
└─ apple
├─ banana
| ├─ cantaloupe
| └─ durian
└─ eggplant
请注意
apple
子节点的最左侧,最后没有|
,因为它们被抑制了。或中间为空:
>>> text='''apple: banana
banana: cantaloupe durian
eggplant:'''
>>> draw_tree(parser(text))
├─ apple
| └─ banana
| ├─ cantaloupe
| └─ durian
└─ eggplant
关于python - 在bash中可视化树,就像unix "tree"的输出一样,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32151776/