タイムスタンプ順にファイルを検索する

タイムスタンプ順にファイルを検索する

dir通常のファイルが 2 つあります。

file1abc\n、を持ってfile2いますdef\n。これら2つのファイルを以下のようにgzipで圧縮します。

#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz  file2.gz

内容を確認した後、

#find . -type f  -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n

ファイルの作成時間順にファイルの内容を取得できません。 期待される出力は常に ですabc\ndef\n

興味深い観察:実際の出力は時々、def\nabc\nそして時々abc\ndef\n

質問:

タイムスタンプの順(降順/昇順)でファイルを検索するにはどうすればいいですか?

答え1

によって報告されるファイルの順序は、findユーザーには分かりません。ディレクトリに表示される順序である可能性があります。一部のfind実装では、パフォーマンスを向上させるために、inode 番号またはその他の基準で順序を変更します。順序を変更する唯一の方法は、ブランチの前にリーフを処理/出力するように-depth指示する述語を使用することです。find

の代わりに、の再帰 glob 機能findを使用することもできます。zsh

zgrep whatever ./**/*.gz(D.Om)

globOm修飾子は、最終変更時間 (古い順) で並べ替えます。は通常のファイルのみ (の.と同等) 用で、はデフォルトで行われるように隠し (ドット) ファイルを含める場合に使用します。find-type fDfind

もしあなたが引数リストが長すぎますエラーが発生した場合は、次を使用できますzargs:

autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever

bash(または Ksh スタイルのプロセス置換をサポートする任意のシェル) と最近の GNU ツールを使用すると、同等のものは次のようになります。

xargs -r0a <(
  export LC_ALL=C
  find . -type f -name '*.gz' -printf '%T@\t%p\0' |
    sort -zn | cut -zf2-) zgrep whatever

答え2

1 つのオプションは、ファイル パスとともにファイルのタイムスタンプを出力し、それによって並べ替えてから削除することです。

find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat 

ファイル名に潜在的に危険な文字(スペースなど)が含まれる可能性がある場合は、

xargs zcat 

xargs -d "\n" zcat 

ファイル名に改行文字を含める必要がある場合は、@stéphane-chazelas の回答に詳述されているように、レコードを終了するためにヌルバイトを使用できます (ただし、実際には問題になることはほとんどありません)。

答え3

残念ながら、find コマンドは、出力がアルファベット順またはファイルの経過時間順になることが保証されないような動作をします。次のようなコマンドを試してみてください。

ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1

関連情報