簡體   English   中英

如何對find的輸出進行排序?

[英]How do I sort the output of 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
find ./lib/app -type f | sort | tee myFile

恕我直言,那里不需要

似乎您希望在子目錄中的所有文件之前列出子目錄中的文件。 那根本不是標准的排序。 我認為該算法在概念上應該是:

  1. 如果兩個文件名之間最長的公共初始子路徑是X ,則名稱是X/AX/B
  2. 如果AB都包含一個或多個斜杠,請對AB進行直線比較。
  3. 否則,如果AB都不包含斜杠,請對AB進行直線比較。
  4. 否則,如果A包含一個斜杠而B不包含,則在A之前對B進行排序。
  5. 否則( B包含一個斜杠,而A不包含,所以)在B之前對A進行排序。

在樣本數據中:

  • 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

我發現我可以這樣做,以便首先從最頂層的目錄中獲取文件,然后從子文件夾中按字母順序獲取文件:

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

如果目錄結構發生更改,它可能會剎車,但是如果有人有更好的主意,請告訴我。

假設您需要先排減斜杠的路徑名,然后:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM