递归查找所有比给定时间新的文件


72

给定一个time_t:

⚡ date -ur 1312603983
Sat  6 Aug 2011 04:13:03 UTC

我正在寻找一个bash单线列出所有较新的文件。比较应考虑时区。

就像是

find . --newer 1312603983

但是使用time_t而不是文件。

Answers:


20

这有点circuit回,因为touch它没有原始time_t值,但是应该可以在脚本中非常安全地完成此工作。(MacOS X中存在的-r选项date;我没有仔细检查GNU。)可以通过直接在touch命令行中编写命令替换来避免使用“ time”变量。

time=$(date -r 1312603983 '+%Y%m%d%H%M.%S')
marker=/tmp/marker.$$
trap "rm -f $marker; exit 1" 0 1 2 3 13 15
touch -t $time $marker
find . -type f -newer $marker
rm -f $marker
trap 0

2
我只是想记住如何查找比另一个文件更新的文件-find . -type f -newer <file>正是我要寻找的东西
Randall

1
怎么trap办?
斯图尔特

3
@Stewart:第一个陷阱可确保如果脚本退出或通过HUP,INT,QUIT,PIPE或TERM信号发出信号,则将删除临时文件,并且脚本以状态1退出(“不成功”,因此“失败')。第二个陷阱可确保取消原始的“退出时陷阱”,以便脚本成功退出。第一个陷阱不会尝试捕获所有可能的信号。它只是捕获了最可能使用的那些。某些信号(KILL,STOP)根本无法捕获。
乔纳森·勒夫勒

@JonathanLeffler那么那些结尾的数字就是信号ID?
斯图尔特

2
@Stewart:是的;您可以根据需要使用HUP之类的名称,并且不需要为过时的shell进行编程。当我了解到,名字不是一个选择,所以我不使用它们。此外,数字更紧凑,我trap经常在创建临时文件的shell脚本中键入命令。当然,这主要是懒惰,不是真正可测量的节省时间。我从来没有费心检查我当前使用的所有shell是否都支持名称,因为它们都支持数字。的名称0是EXIT。
乔纳森·勒夫勒

156

您可以找到每个文件在过去一天创建/修改的内容,请使用以下示例:

find /directory -newermt $(date +%Y-%m-%d -d '1 day ago') -type f -print

要查找上周的所有内容,请使用“ 1周前”或“ 7天前”


4
遗憾的newerXY是,这是一个相对较新的扩展,默认情况下不可用,例如在CentOS 5.8
Dima Tisnek 2014年

9
您不需要date命令,因为-newermt的参数被视为-ddate的参数。
凯文·考克斯

6
在OSX Mountain Lion(手册页指示2007 BSD?)上,似乎date要求格式必须在最后,并且该-d选项实际上是该-v选项,因此上面的命令看起来像find /directory -newermt $(date -v-1d +%Y-%m-%d) -type f -print
sameers

通过测试我发现-newermt实际上意味着“相同或更高的”,这是不是由字“新”建议:echo hello >./foo.txt; find -maxdepth 1 -name foo.txt -newermt @$(stat -c%Y foo.txt)回报./foo.txt。虽然echo hello >./foo.txt; find -maxdepth 1 -name foo.txt -newermt @$(( $(stat -c%Y foo.txt)+1 ))不返回任何东西。这是find来自GNU findutils 4.4.2。
scoobydoo,2015年

7
实际上,您不需要该$(date ...)部分。-newerXt接受任何涉及后-ddate命令,因此-newermt '1 day ago'很好地工作。
RealSkeptic 2015年

39

也许有人可以使用它。递归查找在特定时间范围内修改的所有文件,只需运行:

find . -type f -newermt "2013-06-01" \! -newermt "2013-06-20"

3
真好!我使用-not否定-newermtfind . -type f -not -newermt "2017-10-01"
runlevel0

@Stefan会发生什么?逻辑'不会从find命令中省略吗?
亚历山大·卡斯卡

还要记住,您可以将输出重定向到文件以供以后使用,例如find . -type f -newermt "2013-06-01" \! -newermt "2013-06-20" > output.txt
FlameStorm

15

给定的unix时间戳记(自纪元以来的秒数)1494500000,请执行以下操作:

find . -type f -newermt "$(date '+%Y-%m-%d %H:%M:%S' -d @1494500000)"

要将这些文件grep表示为“ foo”:

find . -type f -newermt "$(date '+%Y-%m-%d %H:%M:%S' -d @1494500000)" -exec grep -H 'foo' '{}' \;

这是一个很好的答案,需要更多支持。不过有一条评论。日期格式参数应改为:find。-type f -newermt“ $(date -d @ 1494500000)+'%Y-%m-%d%H:%M:%S'”并找到。-f -newermt“ $(date -r 1494500000)+'%Y-%m-%d%H:%M:%S'”在MacOSX上
Jacques

6

您也可以在没有标记文件的情况下执行此操作。

迄今为止的%s格式是自该时期以来的秒数。find的-mmin标志以分钟为单位接受参数,因此将秒数之差除以60。age前面的“-”表示查找最后修改小于age的文件。

time=1312603983
now=$(date +'%s')
((age = (now - time) / 60))
find . -type f -mmin -$age

对于较新版本的gnu find,您可以使用-newermt,这使它变得微不足道。


5

假设发布了新版本,find -newermt功能强大:

find -newermt '10 minutes ago' ## other units work too, see `Date input formats`

或者,如果您要指定a time_t(距离epoch的秒数):

find -newermt @1568670245

仅供参考,-newermt未在手册页中直接列出以供查找。而是显示为-newerXY,其中XY占位符为mt。其他替代产品是合法的,但不适用于此解决方案。

来自man find -newerXY

时间规范被解释为GNU date的-d选项的参数。

因此,以下等效于初始示例:

find -newermt "$(date '+%Y-%m-%d %H:%M:%S' -d '10 minutes ago')" ## long form using 'date'
find -newermt "@$(date +%s -d '10 minutes ago')" ## short form using 'date' -- notice '@'

date -d(和find -newermt)参数是相当灵活,但文档是模糊的。这似乎是一个要点:日期输入格式


您还可以执行以下操作:find -newermt '4:00pm yesterday'
Brent Bradburn

0

因此,还有另一种方式(并且在某种程度上可以移植_

(python <<EOF
import fnmatch
import os
import os.path as path
import time

matches = []
def find(dirname=None, newerThan=3*24*3600, olderThan=None):
    for root, dirnames, filenames in os.walk(dirname or '.'):
        for filename in fnmatch.filter(filenames, '*'):
            filepath = os.path.join(root, filename)
            matches.append(path)
            ts_now = time.time()
            newer = ts_now - path.getmtime(filepath) < newerThan
            older = ts_now - path.getmtime(filepath) > newerThan
            if newerThan and newer or olderThan and older: print filepath
    for dirname in dirnames:
        if dirname not in ['.', '..']:
            print 'dir:', dirname
            find(dirname)
find('.')
EOF
) | xargs -I '{}' echo found file modified within 3 days '{}'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.