我想找到某个目录中最旧文件的年龄,或者如果该目录中没有任何文件则返回 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 并抑制错误打印输出。
答案1
与zsh
和perl
:
perl -le 'print 0+-M $ARGV[0]' /path/to/dir/*(N-Om[1])
D
(如果您还想考虑隐藏文件(但不是.
nor ..
),请添加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
:为该球体打开。因此,如果目录中没有文件,则扩展为空,导致perl
's-M
返回undef
。-
:导致下一个全局限定符应用于符号链接的目标Om
:按修改时间反转(大写)顺序(因此从最旧到最新,例如ls -rt
)[1]
:仅选择第一个匹配的文件
-M file
:获取文件内容的年龄。0+
或86400*
强制转换为数字(针对这种undef
情况)。
答案2
如果必须是一行:
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}
初始化m
为d
$0 < m {m = $0}
跟踪最小值m
END {print d - m}
打印差异。