web-dev-qa-db-ja.com

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

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

file1にはabc\nfile2には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

質問:

タイムスタンプの順(減少/増加)でファイルを見つける方法は?

4
overexchange

findによって報告されるファイルの順序は、ユーザーには不透明です。ディレクトリに表示される順序にすることができます。一部のfind実装は、パフォーマンスを向上させるために、iノード番号またはその他の基準でそれらを並べ替えます。順序を変更できる唯一の方法は、-depth述語を使用することです。この述語はfindに、分岐が存在するブランチの前にリーフを処理/出力するように指示します。

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

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

Omグロブ修飾子は、最終変更時間(古いものから)でソートします。 .は通常のファイルのみ(find-type fと同等)の場合、Dfindのような非表示(ドット)のファイルを含めますデフォルト。

arg list too longエラーが発生した場合は、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
3

残念ながら、findコマンドは、出力がアルファベット順またはファイル経過時間順であることが保証されない方法で機能します。あなたは次のようなことを試すかもしれません:

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

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の回答で詳しく説明されているように、ヌルバイトを使用してレコードを終了できます(これは実際には問題になることはめったにありません)。

1
zeppelin