按時間戳順序查找文件

按時間戳順序查找文件

dir有兩個常規文件。

file1abc\nfile2def\n。用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處理/輸出在它們所在的分支之前離開。

作為 的替代方案find,您可以使用zsh的遞歸 glob 功能:

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

globOm限定符依最後修改時間排序(最舊的在前)。.僅適用於常規檔案(相當於find's -type f),D包括find預設情況下隱藏的(點)檔案。

如果你得到一個arg 列表太長錯誤,您可以使用zargs

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

使用bash(或任何支援 Ksh 樣式進程替換的 shell)和最新的 GNU 工具,等效項將是:

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

答案2

一種選擇是輸出檔案時間戳記以及檔案路徑,按其排序,然後將其刪除:

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

相關內容