将类似“find"的输出转换为类似“树"的输出 [英] convert a `find` like output to a `tree` like output

查看:32
本文介绍了将类似“find"的输出转换为类似“树"的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是以树格式输出 ZipArchive() 的通用版本 问题.

<小时>

就在我浪费时间编写这个(*nix 命令行)实用程序之前,最好看看是否有人已经编写了它.我想要一个实用程序,它将获得一个列表作为其标准输入,例如 find(1) 返回的列表,并输出类似于 tree(1)

例如:

输入:

/fruit/apple/green/水果/苹果/红色/水果/苹果/黄色/水果/香蕉/绿色/水果/香蕉/黄色/水果/橙色/绿色/水果/橙色/橙色/i_want_my_mommy/人/人/鲍勃/人/人/大卫/人/女人/前夕

输出

<代码>/|-- 水果/||-- 苹果/|||-- 绿色|||-- 红色||`--黄色||-- 香蕉/|||-- 绿色||`--黄色|`--橙色/||-- 绿色|`--橙色|-- i_want_my_mommy`--人/|-- 男人/||-- 鲍勃|`——大卫`--女性/`-- 前夕

用法应该是这样的:

list2tree --delimiter="/" <输入 >输出

<小时>

Edit0:好像我并不清楚这个练习的目的.我喜欢树的输出,但我希望它用于任意输入.它可能不是任何文件系统命名空间的一部分.

Edit1:修复了输出上的 person 分支.谢谢,@Alnitak.

解决方案

我创建了一个 Perl 脚本,用于拆分路径(在/"上),创建一个哈希树,然后使用 Data::TreeDumper 打印该树.有点 hacky,但它有效:

#!/usr/bin/perl使用严格;使用警告;使用 Data::TreeDumper;我的 %tree;而 (<>) {我的 $t = \%tree;foreach 我的 $part (split m!/!, $_) {下一个如果 $part eq '';chomp $part;$t->{$part} ||= {};$t = $t->{$part};}}子检查树{我的 $t = 班次;foreach my $hash (values %$t) {undef $hash 除非键 %$hash;check_tree($hash);}}check_tree(\%tree);我的 $output = DumpTree(\%tree);$output =~ s/= undef.*//g;$output =~ s/\[H\d+\].*//g;打印 $output;

输出如下:

<前>$ perl test.pl test.data|- 水果||- 苹果|||- 绿色|||- 红色||`-黄色||- 香蕉|||- 绿色||`-黄色|`- 橙色||- 绿色|`- 橙色|- i_want_my_mommy`- 人|- 男士||- 鲍勃|`-大卫`- 女性`- 前夕

This question is a generalized version of the Output of ZipArchive() in tree format question.


Just before I am wasting time on writing this (*nix command line) utility, it will be a good idea to find out if someone already wrote it. I would like a utility that will get as its' standard input a list such as the one returned by find(1) and will output something similar to the one by tree(1)

E.g.:

Input:

/fruit/apple/green
/fruit/apple/red
/fruit/apple/yellow
/fruit/banana/green
/fruit/banana/yellow
/fruit/orange/green
/fruit/orange/orange
/i_want_my_mommy
/person/men/bob
/person/men/david
/person/women/eve

Output

/
|-- fruit/
|   |-- apple/
|   |   |-- green
|   |   |-- red
|   |   `-- yellow
|   |-- banana/
|   |   |-- green
|   |   `-- yellow
|   `-- orange/
|       |-- green
|       `-- orange
|-- i_want_my_mommy
`-- person/
    |-- men/
    |   |-- bob
    |   `-- david
    `-- women/
        `-- eve

Usage should be something like:

list2tree --delimiter="/" < Input > Output


Edit0: It seems that I was not clear about the purpose of this exercise. I like the output of tree, but I want it for arbitrary input. It might not be part of any file system name-space.

Edit1: Fixed person branch on the output. Thanks, @Alnitak.

解决方案

I whipped up a Perl script that splits the paths (on "/"), creates a hash tree, and then prints the tree with Data::TreeDumper. Kinda hacky, but it works:

#!/usr/bin/perl
use strict;
use warnings;

use Data::TreeDumper;

my %tree;
while (<>) {
    my $t = \%tree;
    foreach my $part (split m!/!, $_) {
        next if $part eq '';
        chomp $part;
        $t->{$part} ||= {};
        $t = $t->{$part};
    }
}
sub check_tree {
    my $t = shift;
    foreach my $hash (values %$t) {
        undef $hash unless keys %$hash;
        check_tree($hash);
    }    
}
check_tree(\%tree);
my $output = DumpTree(\%tree);
$output =~ s/ = undef.*//g;
$output =~ s/ \[H\d+\].*//g;
print $output;

Here's the output:

$ perl test.pl test.data

|- fruit 
|  |- apple 
|  |  |- green
|  |  |- red
|  |  `- yellow
|  |- banana 
|  |  |- green
|  |  `- yellow
|  `- orange 
|     |- green
|     `- orange
|- i_want_my_mommy
`- person 
   |- men 
   |  |- bob
   |  `- david
   `- women 
      `- eve

这篇关于将类似“find"的输出转换为类似“树"的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆