【问题标题】:Recursively find all files newer than a given time [closed]递归查找比给定时间更新的所有文件[关闭]
【发布时间】:2021-12-17 02:34:20
【问题描述】:

给定一个time_t:

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

我正在寻找列出所有更新文件的 bash 单行程序。比较应考虑时区。

类似

find . --newer 1312603983

但使用time_t 而不是文件。

【问题讨论】:

    标签: linux bash


    【解决方案1】:

    您可以找到在最后一天创建/修改的每个文件,使用以下示例:

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

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

    【讨论】:

    • 可悲的是 newerXY 是一个相对较新的扩展,默认情况下不可用,例如在 CentOS 5.8 中
    • 您不需要 date 命令,因为 -newermt 的参数被视为 date 的 -d 参数。
    • 在 OSX Mountain Lion 上(手册页指示 2007 BSD?),似乎 date 要求格式位于末尾,而 -d 选项实际上是 -v 选项,所以上面的命令看起来像find /directory -newermt $(date -v-1d +%Y-%m-%d) -type f -print
    • 通过测试我发现 -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 )) 不返回任何内容。这是来自 GNU findutils 4.4.2 的find
    • 事实上,您不需要$(date ...) 部分。 -newerXt 接受 date 命令中 -d 之后的任何内容,因此 -newermt '1 day ago' 工作得很好。
    【解决方案2】:

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

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

    【讨论】:

    • 不错!我使用-not 否定-newermtfind . -type f -not -newermt "2017-10-01"
    • @Stefan 从查找命令中省略逻辑 'NOT 会发生什么?
    • 另外请记住,您可以将输出重定向到文件以供以后使用,例如 find . -type f -newermt "2013-06-01" \! -newermt "2013-06-20" > output.txt
    【解决方案3】:

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

    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
    

    【讨论】:

    • 我只是想记住如何找到比另一个文件更新的文件 - find . -type f -newer <file> 正是我想要的
    • trap 有什么作用?
    • @Stewart:第一个陷阱确保如果脚本退出或使用 HUP、INT、QUIT、PIPE 或 TERM 信号发出信号,则临时文件被删除,脚本以状态 1 退出(即是“不成功”,因此是“失败”)。第二个陷阱确保取消原始的“退出时陷阱”,以便脚本成功退出。第一个陷阱不会尝试捕获所有可能的信号;它只会捕获最有可能被使用的那些。有些信号(KILL、STOP)根本无法捕捉到。
    • @JonathanLeffler 那么这些尾随数字是信号 ID 吗?
    • @Stewart:是的;如果您愿意,可以使用 HUP 之类的名称,并且不需要为过时的 shell 编程。当我了解到,名字不是一个选项,所以我不使用它们。此外,数字更紧凑,我经常在创建临时文件的 shell 脚本中键入trap 命令。当然,这主要是懒惰,而不是真正可衡量的时间节省。我从来没有费心检查我目前使用的所有 shell 是否都支持名称,因为它们都支持数字。 0 的名称是 EXIT。
    【解决方案4】:

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

    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'" 并找到 . -type f -newermt "$(date -r 1494500000) +'%Y-%m-%d %H:%M:%S'" 在 MacOSX 上
    【解决方案5】:

    假设是现代版本,find -newermt 功能强大:

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

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

    find -newermt @1568670245
    

    作为参考,-newermt 没有直接列在 find 的手册页中。相反,它显示为-newerXY,其中XYmt 的占位符。其他替换是合法的,但不适用于此解决方案。

    来自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)参数非常灵活,但文档晦涩难懂。这是一个似乎很重要的来源:Date input formats

    【讨论】:

    • 你也可以这样做:find -newermt '4:00pm yesterday'
    【解决方案6】:

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

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

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

    对于较新版本的 gnu find,您可以使用 -newermt,这很简单。

    【讨论】:

      【解决方案7】:

      所以还有另一种方式(在某种程度上它是可移植的_

      (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 '{}'
      

      【讨论】:

      • 你能解释一下代码在做什么吗?
      【解决方案8】:

      PowerShell available on Linux 有一段时间了,所以我建议使用它,因为它不仅处理纯文本,还处理真实对象,因此可以避免格式化并使任务更容易

      ls -recurse | where lastwritetime -gt ((get-date).AddDays(-1))
      

      【讨论】:

        【解决方案9】:

        这是另一种方式。您可以使用touch -dfind /dir -newer 命令递归查找比给定时间戳更新的文件。

        例如,如果您需要查找比“2018 年 6 月 1 日 11:02”更新的文件,您可以创建具有此创建日期的文件。

        touch -d '1 June 2018 11:02' ref_timestamp
        

        然后,您可以在find 命令中使用文件时间戳作为参考。

        find /dir -newer ref_timestamp
        

        【讨论】:

          猜你喜欢
          • 2017-10-27
          • 1970-01-01
          • 1970-01-01
          • 2012-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-19
          • 2015-01-21
          相关资源
          最近更新 更多