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. 2つのファイル名の間の最も長い共通の初期サブパスがでXある場合、名前はとです。X/AX/B
  2. 両方に1つ以上のスラッシュが含まれている場合はABAとのB)ストレートストリング比較を実行します。
  3. それ以外の場合、スラッシュAも含まれていない場合は、(との)Bストレート文字列比較を実行します。AB
  4. それ以外の場合A、スラッシュが含まれていて含まれてBいない場合は、のB前に並べ替えますA
  5. それ以外の場合(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 に答える