dir
2つの一般的なファイルがあります。
file1
はいabc\n
、file2
ありますdef\n
。以下のようにgzipを使用して2つのファイルを圧縮します。
#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
修飾子は最後の修正時刻に基づいてソートされます(最も古いものから)。デフォルトでは、隠し(ドット)ファイルを含む通常のファイル('sと同じ).
でのみ機能します。find
-type f
D
find
あなたが得る場合引数のリストが長すぎます。エラーが発生しました。以下を使用できますzargs
。
autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever
(またはKshスタイルのプロセス置換をサポートするシェル)と最新のGNUツールを使用するbash
と、次のようになります。
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の回答で詳しく説明されているように、NULLバイトを使用してレコードを終了できます(実際にはほとんど問題はありません)。
答え3
残念ながら、 find コマンドがどのように機能するかに応じて、出力がファイルの年齢に応じてアルファベット順または時系列でソートされるという保証はありません。次のように試すことができます。
ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1