![列出比给定时间戳更新的所有文件并对它们进行排序](https://linux22.com/image/28845/%E5%88%97%E5%87%BA%E6%AF%94%E7%BB%99%E5%AE%9A%E6%97%B6%E9%97%B4%E6%88%B3%E6%9B%B4%E6%96%B0%E7%9A%84%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6%E5%B9%B6%E5%AF%B9%E5%AE%83%E4%BB%AC%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F.png)
我想列出比以下时间更新的所有文件(按日期排序)时间戳20130207003851
仅在目录 /tmp 中采用格式。子目录可以省略。
使用 SUSE Linux Enterprise Server 11。
输出格式应该是
S0002948.LOG Feb 7 03:28
S0002935.LOG Feb 7 05:58
S0002952.LOG Feb 7 09:58
S0002940.LOG Feb 7 11:58
查找 /tmp -newermt "2013 年 2 月 7 日" -ls列出了我想要的文件,但是
- 如何使用 20130207003851 格式的时间戳
- 我如何对输出进行排序?
- 我怎样才能只显示文件名和日期。先文件名再日期?
ps 我不想使用 touch 来创建查找的参考文件
嘘
find -newermt "20130207003851" -ls
find: I cannot figure out how to interpret `20130207003851' as a date or time
答案1
find
支持很多日期输入格式。最简单的获取格式是 YYYYMMDD HH:MM:SS。您已经拥有正确顺序的数字,您所要做的就是提取第一组(${timestamp%??????}
:提取除最后 6 个字符之外的所有字符;${timestamp#????????}
:提取除前 8 个字符之外的所有字符),然后继续,附加标点符号,然后添加下一组当你继续前进时。
timestamp=20130207003851
timestring=${timestamp%??????}; timestamp=${timestamp#????????}
timestring="$timestring ${timestamp%????}"; timestamp=${timestamp#??}
timestring="$timestring:${timestamp%??}:${timestamp#??}"
在 bash(以及 ksh 和 zsh)中,但不是在 ash 中,您可以使用更具可读性的${STRING_VARIABLE:OFFSET:LENGTH}
构造。
timestring="${timestamp:0:8} ${timestamp:8:2}:${timestamp:10:2}:${timestamp:12:2}"
要按日期对文件进行排序,请打印出日期前面的文件名并对其进行排序,然后去掉日期前缀。使用-printf
来控制输出格式。打印由 确定的修改时间的一部分;如果是,您将获得自 Unix 纪元以来的秒数。下面我打印了三个制表符分隔的列:可排序格式的时间、文件名和人类可读格式的时间;删除第一列,并调用将制表符替换为足够的空格以容纳所有预期的文件名(根据需要调整 40)。此代码假设文件名中没有换行符或制表符。%TX
X
X
@
cut -f 2-
expand
find -maxdepth 1 -type f \
-newermt "$timestring" -printf '%T@\t%f\t%Tb %Td %TH:%TM\n' |
sort -k1n |
cut -f 2- |
expand -t 40
答案2
和zsh
:
zmodload zsh/stat
newer() {
local t
zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY && (( t >= timestamp ))
}
timestamp=20130207003851
print -rl -- /tmp/*(D.Om+newer)
newer
对于更新的文件,该函数返回 true $timestamp
(请注意,尽管zsh
'szstat
不支持亚秒精度)。
然后我们要做的就是使用zsh
globbing 限定符:D
包含点文件、.
仅考虑常规文件、Om
按修改时间排序,以及+newer
调用newer
函数来确定选择哪个文件。
如果还想显示文件时间戳,可以更改newer
为:
newer() {
local t
zstat -A t -F %Y%m%d%H%M%S +mtime -- $REPLY &&
REPLY+=$'\t'$t &&
(( t >= timestamp ))
}
请注意,文件名生成的结果将包括时间戳,这意味着您不能再使用它们作为文件名。