Shell-Script

在一行中查找最舊文件的年齡或返回零

  • April 2, 2020

我想查找某個目錄中最舊文件的年齡,如果此目錄中沒有任何文件,則返回 0。我還需要一個單行命令來完成它。到目前為止,這是我在目錄中查找最舊文件的年齡(以秒為單位)的命令:

expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))

問題是,如果沒有文件,它會返回以下錯誤:

$ expr $(($(date +%s) - $(stat -c %Y $(ls -lt /path/to/dir/ | tail -1 | awk '{print $NF}'))))
stat: cannot stat ‘0’: No such file or directory
-bash: 1554373460 - : syntax error: operand expected (error token is "- ")

所以在這種情況下,我希望命令只返回 0 並抑制錯誤列印輸出。

如果必須是一行:

stat -c %Y ./* 2>/dev/null | awk -v d="$(date +%s)" 'BEGIN {m=d} $0 < m {m = $0} END {print d - m}'
  • stat -c %Y ./* 2>/dev/null列印所有文件的時間戳,忽略錯誤(所以沒有文件導致沒有輸出)

  • 使用 awk:

    • -v d="$(date +%s)"將目前時間戳保存在變數中d
    • BEGIN {m=d}初始化md
    • $0 < m {m = $0}跟踪最小值m
    • END {print d - m}列印差異。

zshperl:_

perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])

D(如果您還想考慮隱藏文件(但不考慮),請添加 glob.限定符)..

請注意,對於符號連結,它考慮了它解析到的文件的修改時間。刪除-glob 限定符中的 in 以考慮符號連結的修改時間(並使用(lstat$ARGV[0] && -M _)inperl來獲取符號連結的年齡)。

這給出了以天為單位的年齡。乘以 86400 得到秒數:

perl -le 'print 86400*-M $ARGV[0]' /path/to/dir/*(N-Om[1])
  • (N-Om[1]):全域限定符:

    • N``nullglob:為那個 glob打開。因此,如果目錄中沒有文件,則擴展為空,導致perl’s-M返回undef
    • -: 導致下一個全域限定符應用於符號連結的目標
    • Om:按修改時間反轉(大寫)順序(所以從最舊到最新ls -rt
    • [1]: 只選擇第一個匹配的文件
  • -M file:獲取文件內容的年齡。

  • 0+86400*強制轉換為數字(對於這種undef情況)。

引用自:https://unix.stackexchange.com/questions/510472