如何对find的输出进行排序?

时间:2012-11-21 15:13:02

标签: bash sorting find

在下面的代码段中,我合并了许多文件和中间的换行符。但是,文件的顺序不代表我的目录结构。

如下所示调用sort无效。我做错了什么?

find ./lib/app -type f | sort | \
xargs awk 'ENDFILE {print ""} {print}' > myFile

当前文件顺序:

./lib/app/b/file
./lib/app/config.json
./lib/app/d/file

我需要的文件顺序:

./lib/app/config.json
./lib/app/b/file
./lib/app/d/file

4 个答案:

答案 0 :(得分:2)

find ./lib/app -type f | sort | tee myFile

恕我直言,那里不需要

答案 1 :(得分:1)

您希望在子子目录中的任何文件之前列出子目录中的文件。这根本不是标准的。我认为算法应该是概念性的:

  1. 如果两个文件名之间的最长公共初始子路径为X,则名称为X/AX/B
  2. 如果AB都包含一个或多个斜杠,请进行直接字符串比较(AB)。
  3. 否则AB都不包含斜杠,请进行直接字符串比较(AB)。
  4. 如果A包含斜杠且B没有斜杠,请在B之前对A进行排序。
  5. 否则B包含斜杠,A不包含斜杠,因此A之前排序B
  6. 在样本数据中:

    • F1 = ./lib/app/b/file
    • F2 = ./lib/app/config.json
    • F3 = ./lib/app/d/file
    • F4 = ./lib/app/b/a/file
    • F5 = ./lib/app/b/other

    比较

    Names      X             A              B              Rule   Result
    F1, F2    ./lib/app/     b/file         config.json    4      F2 < F1
    F1, F3    ./lib/app/     b/file         d/file         2      F1 < F3
    F1, F4    ./lib/app/b/   file           a/file         5      F1 < F4
    F1, F5    ./lib/app/b    file           other          3      F1 < F5
    F2, F3    ./lib/app/     config.json    d/file         5      F2 < F3
    F2, F4    ./lib/app/     config.json    b/a/file       5      F2 < F4
    F2, F5    ./lib/app/     config.json    b/other        5      F2 < F5
    F3, F4    ./lib/app/     d/file         b/a/file       2      F4 < F3
    F3, F5    ./lib/app/     d/file         b/other        2      F5 < F3
    F4, F5    ./lib/app/b    a/file         other          3      F5 < F3
    

    在Perl中编码:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    my @files;
    while (<>)
    {
        chomp;
        push @files, $_;
    }
    
    sub pathsorter
    {
        my(@abits) = split /\//, $a;
        my(@bbits) = split /\//, $b;
    
    
        my $na = scalar(@abits);
        my $nb = scalar(@bbits);
        my $nbits = (($na < $nb) ? $na : $nb) - 1;
        my $i;
        for ($i = 0; $i < $nbits; $i++)
        {
            last if ($abits[$i] ne $bbits[$i]);
        }
    
        # abits[0..$i] == bbits[0..$i] == X
        return $a cmp $b if ($i < $nbits);
        return $a cmp $b if ($na == $nb && $i == $nbits);
        return -1 if ($na < $nb);
        return +1 if ($na > $nb);
        return 0;
    }
    
    print "$_\n" foreach (sort pathsorter @files);
    

    输入:

    ./lib/app/b/file
    ./lib/app/config.json
    ./lib/base/basename
    ./lib/app/d/file
    ./lib/app/b/a/file
    ./lib/app/b/other
    ./lib/app/animosity
    ./lib/base/basename
    

    输出:

    ./lib/app/animosity
    ./lib/app/config.json
    ./lib/app/b/file
    ./lib/app/b/other
    ./lib/app/b/a/file
    ./lib/app/d/file
    ./lib/base/basename
    ./lib/base/basename
    

答案 2 :(得分:0)

我发现我可以这样做,从最顶层的目录中获取文件,然后按子文件夹的字母顺序获取文件:

find ./subfolder ./subfolder/*/ -maxdepth 1 -type f

如果目录结构发生变化,它可能会制动,但如果有人有更好的想法,请告诉我。

答案 3 :(得分:0)

假设您需要首先排序较少斜杠的路径名,那么:

find ... |
perl -e 'print sort {(($a =~ tr{/}{/}) <=> ($b =~ tr{/}{/})) or ($a cmp $b)} <>'