相対パス全体の代わりにファイル名に基づいてサブディレクトリglobをソートする方法

相対パス全体の代わりにファイル名に基づいてサブディレクトリglobをソートする方法

次のファイルツリーが与えられた場合:

subdirFoo/2019-06-01-blah.ext
subdirFoo/2019-06-07-blah.ext
subdirFoo/2019-05-02-blah.ext
subdirBar/2019-06-03-blah.ext
subdirBar/2019-05-05-blah.ext
subdirBar/2019-05-13-blah.ext

このファイルを繰り返してパラメータとして渡したいのですが、somecommandフルパスではなくファイル名でソートされた順序で繰り返したいと思います。

通常、globはアルファベット順にソートされますが、次の順序でソートされます。

subdirBar/2019-05-05-blah.ext
subdirBar/2019-05-13-blah.ext
subdirBar/2019-06-03-blah.ext
subdirFoo/2019-05-02-blah.ext
subdirFoo/2019-06-01-blah.ext
subdirFoo/2019-06-07-blah.ext

つまり、ソート時にサブディレクトリが考慮されますが、これは私が望むものではありません。

globをファイル名だけでソートしながら、コマンドがファイルを正しく参照できるようにループのサブディレクトリを維持するにはどうすればよいですか?つまり、ファイルパスが正しくないか欠落しているため、サブディレクトリの削除は機能しません。

つまり、次の順序でソートする必要があります。

subdirFoo/2019-05-02-blah.ext
subdirBar/2019-05-05-blah.ext
subdirBar/2019-05-13-blah.ext
subdirFoo/2019-06-01-blah.ext
subdirBar/2019-06-03-blah.ext
subdirFoo/2019-06-07-blah.ext

zshの解決策が好まれますが、bashやshも問題ありません。

答え1

sortフィールド区切り文字を/2番目のフィールドに設定してソートする必要があります。

答え2

そうはわかりませんが正しいこれは方法ですが、${VAR##*/}glob修飾子にパラメータ置換を入力できますzsh oe

 % printf '%s\n' subdir*/*(.Noe:'REPLY=${REPLY##*/}':)
subdirFoo/2019-05-02-blah.ext
subdirBar/2019-05-05-blah.ext
subdirBar/2019-05-13-blah.ext
subdirFoo/2019-06-01-blah.ext
subdirBar/2019-06-03-blah.ext
subdirFoo/2019-06-07-blah.ext

これにより、最後のパスコンポーネント(ファイル名)に基づいてglob結果がソートされます。 glob修飾子のビットは、:'...':各一致項目に対して実行され、ソートキー(実際の一致項目)REPLYとして使用される値に設定されます。$REPLY

例えばグローバル予選部分zsh: 14.7 ファイル名拡張子

oe と o+ は特別なケースです。それぞれの後には、e glob修飾子と+ glob修飾子で区切られたシェルコードが続きます(上記を参照)。エントリーのファイル名に設定されたREPLYパラメーターと、zsh_eval_contextに追加されたglobsortを使用して、一致する各ファイルに対してコードが実行されます。コードは何らかの方法でREPLYパラメーターを変更する必要があります。戻り値は、ファイル名の代わりに引数値をソートする文字列として使用します。他のソート演算子とは異なり、oeとo +は繰り返すことができますが、すべてのglob式に表示できるすべてのタイプのソート演算子の最大数は12です。

答え3

代わりにglobを使用するようになりましたfind。フィールドごとのソートに関するヒントを提供した@ctrl-alt-delorに感謝します。

for file in `find {subdirFoo,subdirBar} -maxdepth 1 -name 'prefix*.ext' | sort -t / -k 2`; do echo $file; somecommand $file; done

関連情報