将“find”之类的输出转换为“tree”之类的输出

发布于 2024-10-07 01:57:57 字数 1109 浏览 0 评论 0 原文

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


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

例如:

输入:

/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。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

殊姿 2024-10-14 01:57:57

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

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

这样我就可以将 find 的输出提供给 tree

find /foo | tree -d --fromfile .

问题:

  • 如果 tree 读取 /foo/whateverfoo/whatever 那么 foo 将被报告为 .子目录。与 ./whatever 类似:. 将被报告为顶层 下名为 .附加级别>.。因此结果可能不完全符合您的正式期望,总会有一个顶级 . 条目。即使 find 找不到任何内容或抛出错误,它也会在那里。

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

In my Debian 10 I have tree v1.8.0. It supports --fromfile.

--fromfile
Reads a directory listing from a file rather than the file-system. Paths provided on the command line are files to read from rather than directories to search. The dot (.) directory indicates that tree should read paths from standard input.

This way I can feed tree with output from find:

find /foo | tree -d --fromfile .

Problems:

  • If tree reads /foo/whatever or foo/whatever then foo will be reported as a subdirectory of .. Similarly with ./whatever: . will be reported as an additional level named . under the top level .. So the results may not entirely meet your formal expectations, there will always be a top level . entry. It will be there even if find finds nothing or throws an error.

  • Filenames with newlines will confuse tree. Using find -print0 is not an option because there is no corresponding switch for tree.

岁月打碎记忆 2024-10-14 01:57:57

我编写了一个 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

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

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
殊姿 2024-10-14 01:57:57

另一个工具是用 treeify rel="nofollow noreferrer">生锈。

假设你已经安装了 Rust,请使用以下命令获取它:

$ cargo install treeify

An other tool is treeify written in Rust.

Assuming you have Rust installed get it with:

$ cargo install treeify
ぶ宁プ宁ぶ 2024-10-14 01:57:57

所以,我最终写了我希望成为python树实用程序的东西。可以在 http://pytree.org 找到它

So, I finally wrote what I hope will become the python tree utils. Find it at http://pytree.org

醉南桥 2024-10-14 01:57:57

我自己会简单地使用tree,但这是我几天前写的一个简单的东西,可以打印目录树。它不期望来自 find 的输入(这使得与您的要求不同),并且不执行 |- 显示(这可以通过一些小的修改来完成)。你必须像这样调用它 tree ; <初始缩进>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
}

I would simply use tree myself but here's a simple thing that I wrote a few days ago that prints a tree of a directory. It doesn't expect input from find (which makes is different from your requirements) and doesn't do the |- display (which can be done with some small modifications). You have to call it like so tree <base_path> <initial_indent>. intial_indent is the number of characters the first "column" is indented.

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文