0

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

如下所示调用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

4 回答 4

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

恕我直言,那里不需要

于 2012-11-21T15:14:37.877 回答
1

您似乎希望将子目录中的文件列在子目录中的任何文件之前。这根本不是一个标准的排序。我认为该算法在概念上应该是:

  1. 如果两个文件名之间最长的公共初始子路径是X,则名称是X/AX/B
  2. 如果两者都A包含B一个或多个斜杠,则进行直字符串比较(ofAB)。
  3. 否则,如果既不A也不B包含斜线,则进行直字符串比较(ofAB)。
  4. 否则,如果A包含斜线B且不包含斜线,则在 .B之前排序A
  5. Else (B包含一个斜线并且A没有,所以) 排序A在 之前B

在样本数据中:

  • 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
于 2012-11-21T19:29:43.193 回答
0

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

find ... |
perl -e 'print sort {(($a =~ tr{/}{/}) <=> ($b =~ tr{/}{/})) or ($a cmp $b)} <>'
于 2012-11-21T18:01:57.457 回答
0

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

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

如果目录结构发生变化,它可能会停止,但如果有人有更好的主意,请告诉我。

于 2012-11-21T17:38:33.897 回答