次のファイルツリーが与えられた場合:
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