将`find`之类的输出转换为`tree`之类的输出

Che*_*evy 4 unix tree text-processing utility

该问题是ZipArchive()输出的树形格式问题的广义版本。


在我浪费时间编写此(* nix命令行)实用程序之前,最好先弄清是否有人已经编写了该实用程序。我想要一个实用程序,它将作为其标准输入获得一个列表,例如由返回的列表,find(1)并输出与之相似的列表。tree(1)

例如:

输入:

/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
Run Code Online (Sandbox Code Playgroud)

输出量

/
|-- fruit/
|   |-- apple/
|   |   |-- green
|   |   |-- red
|   |   `-- yellow
|   |-- banana/
|   |   |-- green
|   |   `-- yellow
|   `-- orange/
|       |-- green
|       `-- orange
|-- i_want_my_mommy
`-- person/
    |-- men/
    |   |-- bob
    |   `-- david
    `-- women/
        `-- eve
Run Code Online (Sandbox Code Playgroud)

用法应类似于:

list2tree --delimiter="/" < Input > Output
Run Code Online (Sandbox Code Playgroud)

Edit0:看来我不清楚此练习的目的。我喜欢tree的输出,但我希望将其用于任意输入。它可能不属于任何文件系统名称空间。

编辑1:固定person输出上的分支。谢谢,@ Alnitak。

Kam*_*ski 14

在我的 Debian 10 中,我有tree v1.8.0. 它支持--fromfile.

--fromfile
从文件而不是文件系统读取目录列表。命令行上提供的路径是要读取的文件而不是要搜索的目录。点 ( .) 目录表示tree应从标准输入读取路径。

这样我就可以使用tree以下输出find

find /foo | tree -d --fromfile .
Run Code Online (Sandbox Code Playgroud)

问题:

  • 如果tree读取/foo/whateverfoo/whatever则将foo被报告为的子目录.。类似地,./whatever:.将被报告为在顶级下命名的附加级别。所以结果可能并不完全符合你的正式期望,总会有一个顶级条目。即使什么也没找到或抛出错误,它也会在那里。...find

  • 带有换行符的文件名会造成混淆tree。使用find -print0不是一个选项,因为 没有相应的开关tree


Dan*_*ing 5

我整理了一个Perl脚本,该脚本分割路径(在“ /”上),创建哈希树,然后使用Data :: TreeDumper打印该树。Kinda hacky,但是它可以工作:

#!/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;
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ perl test.pl test.data

|-水果 
| |-苹果
| | |-绿色
| | |-红色
| | `-黄色
| |-香蕉
| | |-绿色
| | `-黄色
| `-橙色
| |-绿色
| `-橙色
|-i_want_my_mommy
`-人 
   |-男人 
   | |-鲍勃
   | `-大卫
   `-女人 
      前夕