【问题标题】:convert a `find` like output to a `tree` like output将 `find` 类输出转换为 `tree` 类输出
【发布时间】:2011-05-24 04:21:26
【问题描述】:

此问题是Output of ZipArchive() in tree format 问题的通用版本。


在我浪费时间编写这个(*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

输出

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

用法应该是这样的:

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

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

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

【问题讨论】:

  • 除非您安排输入文件在目录中尾随/,否则输出将不可靠。没有它,过滤器将无法区分空目录和文件。 p.s.你搞砸了树的person 分支......
  • tree 有什么问题(例如tree -F)?
  • 澄清@ring0 的优秀评论:mama.indstate.edu/users/ice/tree

标签: unix tree text-processing utility


【解决方案1】:

我自己会简单地使用tree,但这是我几天前写的一个简单的东西,它打印了一个目录树。它不期望来自 find 的输入(这与您的要求不同)并且不执行 |- 显示(可以通过一些小的修改来完成)。你必须这样称呼它tree &lt;base_path&gt; &lt;initial_indent&gt;intial_indent 是第一个“列”缩进的字符数。

function tree() {
    local root=$1
    local indent=$2
    cd $root
    for i in *
    do
    for j in $(seq 0 $indent)
    do 
        echo -n " "
    done
    if [ -d $i ]
    then
        echo "$i/"
        (tree $i $(expr $indent + 5))
    else
        echo $i
    fi
    done
}

【讨论】:

  • 对不起,我不清楚。请参阅问题中的“编辑:”。我不是在寻找树实用程序本身。 findtree 只是为了说明输入和输出的形式,而不是它的内容。
【解决方案2】:

我编写了一个分割路径(在“/”上)的 Perl 脚本,创建一个哈希树,然后使用 Data::TreeDumper 打印该树。有点 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;

这是输出:

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

【讨论】:

    【解决方案3】:

    所以,我终于写了我希望成为python 树工具的东西。在http://pytree.org找到它

    【讨论】:

      【解决方案4】:

      另一个工具是treeify,写成Rust

      假设你已经安装了 Rust 获取它:

      $ cargo install treeify
      

      【讨论】:

        【解决方案5】:

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

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

        这样我可以用find 的输出来喂tree

        find /foo | tree -d --fromfile .
        

        问题:

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

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

        【讨论】:

          猜你喜欢
          • 2011-08-22
          • 1970-01-01
          • 2020-08-11
          • 2022-10-02
          • 1970-01-01
          • 1970-01-01
          • 2020-01-08
          • 1970-01-01
          • 2020-12-18
          相关资源
          最近更新 更多