在日期范围内查找创建的文件

83

我在工作中使用telnet连接AIX,想知道如何在指定日期范围内查找特定文件夹中的文件。例如:我想查找在2013年8月1日至8月31日期间创建的文件夹X中的所有文件。

观察:

  • 使用“touch”技巧(创建两个空文件以使用“-newer”选项)对我不起作用,因为我在服务器上的用户角色不允许我创建文件。
  • 我需要在特定日期范围内查找,而不是天数(例如:在30天前创建的文件等)。
8个回答

190

如果您使用GNU find,自版本4.3.3开始,您可以执行以下操作:

find -newerct "1 Aug 2013" ! -newerct "1 Sep 2013" -ls

它将接受GNU date -d所接受的任何日期字符串。

您可以将-newerct中的c更改为aBcm,以查看atime/birth/ctime/mtime。

另一个例子- 列出2017年11月6日17:30至22:00之间修改的文件:

find -newermt "2017-11-06 17:30:00" ! -newermt "2017-11-06 22:00:00" -ls

man find提供了完整的细节:

   -newerXY reference
          Compares the timestamp of the current file with reference.  The reference argument is normally the name of a file (and one of its timestamps  is  used
          for  the  comparison)  but  it may also be a string describing an absolute time.  X and Y are placeholders for other letters, and these letters select
          which time belonging to how reference is used for the comparison.

          a   The access time of the file reference
          B   The birth time of the file reference
          c   The inode status change time of reference
          m   The modification time of the file reference
          t   reference is interpreted directly as a time

          Some combinations are invalid; for example, it is invalid for X to be t.  Some combinations are not implemented on all systems; for example B  is  not
          supported on all systems.  If an invalid or unsupported combination of XY is specified, a fatal error results.  Time specifications are interpreted as
          for the argument to the -d option of GNU date.  If you try to use the birth time of a reference file, and the birth time cannot be determined, a fatal
          error  message  results.   If  you  specify a test which refers to the birth time of files being examined, this test will fail for any files where the
          birth time is unknown.

1
有人知道如何按时间对结果列表进行排序吗? - Koshmaar
2
@Koshmaar 根据情况,您可以使用类似于 find ... -exec ls -dilst {} + 的命令。ls 命令的 t 选项将按时间排序;有关其他排序选项,请参阅 ls 手册页。 - codebeard
3
如果文件太多,这种方法就不适用了,因为exec命令可能会被分割。此时您需要使用类似于“find ... -printf'% C@% p \n'| sort”的东西。 - codebeard
尝试执行以下命令:find . -newermt $(date -d "-2 days" +"%Y-%m-%d %k:%M:%S") ! -newermt $(date -d "-1 days" +"%Y-%m-%d %k:%M:%S") -ls,却返回错误信息:find: paths must precede expression: `14:33:20',为什么? - Nikolay Baranenko
我认为应该使用-Btime-newerBt,严格用于创建时间,而c则用于文件更改。 - ArcherEX

62

请尝试以下命令:

find /var/tmp -mtime +2 -a -mtime -8 -ls

这将帮助您在位于/var/tmp文件夹中查找创建时间超过2天但不超过8天的文件。


1
对于 -a(和)标志,那太棒了。 - chiliNUT
3
“-a”可以省略。 - flow2k
这对我有效。至于 +- 符号,以下是来自 find 的 man 页面的说明:+n 表示大于 n, -n 表示小于 n, n 表示恰好为 n。 - whatacold

22

这里有一些不错的解决方案。想分享我的方法,因为它既简短又简单。

我正在使用 find (GNU findutils) 4.5.11

$ find search/path/ -newermt 20130801 \! -newermt 20130831

3
非常好。感谢你,Jason。易于阅读、易于书写,并且具有所需的功能。我不知道“-newerXY”技巧,但通过你的答案,我已经发现了它。 - Xavi Montero
与2年前@codebeard的答案完全相同,只是这里没有描述。 - papo
我认为你的意思是写成 \! -newermt 20130901 - Devon
@papo - 当我发布这个回复时,他的回答没有包含这个解决方案。很可能是在我发布之后才包含在他的回答中的。 - Jason Slobotski
1
我明白了。我的错,我删除了有关重复答案的评论,并将在下次遇到多个相同答案时进行检查。 - papo

11
你可以使用以下内容来查找你需要的东西。
查找早于特定日期/时间的文件:
find ~/ -mtime $(echo $(date +%s) - $(date +%s -d"Dec 31, 2009 23:59:59") | bc -l | awk '{print $1 / 86400}' | bc -l)

或者您可以查找在两个日期之间的文件。第一个日期更近,最后一个日期更早。您可以到秒级别进行搜索,并且不必使用 mtime。您可以使用任何您需要的内容。

find . -mtime $(date +%s -d"Aug 10, 2013 23:59:59") -mtime $(date +%s -d"Aug 1, 2013 23:59:59")

我使用了第二个选项,但是却遇到了这个错误:日期/时间说明中存在无效字符。 用法: date [-u] [+字段描述符] 日期/时间说明中存在无效字符。 用法: date [-u] [+字段描述符] 查找:为-mtime指定一个十进制整数。 用法:find [-H | -L] 路径列表 [谓词列表] - sanjuro8998
AIX... 这是 IBM 在 AIX 中关于 DATE 命令的参考资料。http://pic.dhe.ibm.com/infocenter/aix/v7r1/index.jsp?topic=%2Fcom.ibm.aix.cmds%2Fdoc%2Faixcmds2%2Fdate.htm 如果您能够弄清如何在 AIX 中打印日期,您就可以将其与第二个命令一起使用。抱歉,我不是 AIX 大师。 - EvilKittenLord
这对我有用 - marcobazzani
7
第二个命令无法工作 ;($ ls -cl test_file -rw------- 1 v v 0 Nov 16 22:00 test_file $ find . -mindepth 1 -maxdepth 1 -mtime $(date +%s -d"Nov 16, 2015 22:00:00") -mtime $(date +%s -d"Nov 16, 2015 22:01:00") $ - atti
11
第二个命令不正确。date +%s返回的是自1970年以来的“秒数”,但是find -mtime命令期望的是“距今几天前”的值:-mtime n 文件数据最后修改时间是在n*24小时之前。我建议使用@codebeard的答案,它更方便。 - MarSoft
显示剩余2条评论

7

使用stat获取创建时间。你可以按字典顺序比较格式为YYYY-MM-DD HH:MM:SS的时间。

这在Linux上适用于修改时间,不支持创建时间。在AIX上,-c选项可能不被支持,但是如果没有其他方法可以使用grep来获取信息。

#! /bin/bash
from='2013-08-01 00:00:00.0000000000' # 01-Aug-13
to='2013-08-31 23:59:59.9999999999'   # 31-Aug-13

for file in * ; do
    modified=$( stat -c%y "$file" )
    if [[ $from < $modified && $modified < $to ]] ; then
        echo "$file"
    fi
done

如果我只是将其复制粘贴到终端并执行,它会起作用吗?我无法创建任何文件以将其用作脚本。 - sanjuro8998
如果你的shell是bash,它应该可以。 - choroba
这是什么意思?抱歉,我不熟悉Linux...我是通过Telnet(命令提示符)在Windows上执行这些命令的,这有帮助吗? - sanjuro8998
3
如果您不熟悉目标系统,请不要在 Telnet 中运行任何命令。找一个知道该怎么做的人来帮忙。 - choroba

5
您可以使用以下命令列出在两个特定日期之间的文件:
在当前目录(.)中搜索:
find . -type f -newermt "2019-01-01" ! -newermt "2019-05-01"

/var/any/directory/ 目录中搜索:
find /var/any/directory/ -type f -newermt "2019-01-01" ! -newermt "2019-05-01"

与6年前@codebeard的答案完全相同,只是这里没有描述。 - papo

2

脚本oldfiles

我尝试以更完整的方式回答这个问题,并创建了一个完整的脚本,其中包含选项,帮助您理解find命令。

oldfiles脚本在此存储库中。

要“创建”新的find命令,请使用选项-n(干运行),它将向您打印出所需使用的正确find命令。

当然,如果省略-n,它将只是运行,无需重新输入find命令。

用法:

oldfiles [-v...] ([-h|-V|-n] | {[(-a|-u) | (-m|-t) | -c] (-i | -d | -o| -y | -g) N (-\> | -\< | -\=) [-p "pat"]})
  • 选项分为以下几类:
    • 帮助和信息:

-h, --help : 显示此帮助信息。
-V, --version : 显示版本信息。
-v, --verbose : 打开详细模式(累加)。
-n, --dry-run : 不要运行,仅解释如何创建“查找”命令。

  • 时间类型(访问/使用时间、修改时间或更改状态):

-a or -u : 访问(使用)时间
-m or -t : 修改时间(默认)
-c : inode 状态更改

  • 时间范围(其中 N 是正整数):

-i N : 分钟(默认值,N 等于 1 分钟)
-d N : 天
-o N : 月
-y N : 年
-g N : N 是一个日期(例如:“2017-07-06 22:17:15”)

  • 测试:

-p "pat" : 可选的匹配模式(例如:-p“*.c”查找 c 文件)(默认值为 -p“*”)
-\> : 文件比给定范围更新,即修改时间在其后。
-< : 文件比给定范围旧,即时间在其前(默认值)。
-= : 恰好 N(分钟、天、月、年)的文件。

示例:

  • Find C source files newer than 10 minutes (access time) (with verbosity 3):

    oldfiles -a -i 10 -p"*.c" -\> -nvvv
    Starting oldfiles script, by beco, version 20170706.202054...
    oldfiles -vvv -a -i 10 -p "*.c" -\> -n
    Looking for "*.c" files with (a)ccess time newer than 10 minute(s)
    find . -name "*.c" -type f -amin -10 -exec ls -ltu --time-style=long-iso {} +
    Dry-run
    
  • Find H header files older than a month (modification time) (verbosity 2):

    oldfiles -m -o 1 -p"*.h" -\< -nvv
    Starting oldfiles script, by beco, version 20170706.202054...
    oldfiles -vv -m -o 1 -p "*.h" -\< -n
    find . -name "*.h" -type f -mtime +30 -exec ls -lt --time-style=long-iso {} +
    Dry-run
    
  • Find all (*) files within a single day (Dec, 1, 2016; no verbosity, dry-run):

    oldfiles -mng "2016-12-01" -\=
    find . -name "*" -type f -newermt "2016-11-30 23:59:59" ! -newermt "2016-12-01 23:59:59" -exec ls -lt --time-style=long-iso {} +
    
当然,如果去掉-n,程序会运行find命令并为你省去麻烦。
我希望这能帮助每个人最终学习这些选项:{a,c,t}{time,min}
LS输出:
您还会注意到,ls选项ls OPT也会根据您选择的时间类型进行更改。 oldfiles脚本的克隆/下载链接: https://github.com/drbeco/oldfiles

-1
解释:使用Unix命令find-ctime(创建时间)标志。

find实用程序递归地遍历每个列出的路径的目录树,在树中的每个文件中评估一个表达式(由“主要”和“操作数”组成)。

解决方案:根据官方文档:

-ctime n[smhdw]
             If no units are specified, this primary evaluates to true if the difference
             between the time of last change of file status information and the time find
             was started, rounded up to the next full 24-hour period, is n 24-hour peri-
             ods.

             If units are specified, this primary evaluates to true if the difference
             between the time of last change of file status information and the time find
             was started is exactly n units.  Please refer to the -atime primary descrip-
             tion for information on supported time units.

公式:

find <path> -ctime +[number][timeMeasurement] -ctime -[number][timeMeasurment]

示例:

1.查找在一周前和两周前之间创建的所有内容。

find / -ctime +1w -ctime -2w

2. 在当前目录中查找所有在1天前到3天前创建的JavaScript文件(.js)。

find . -name "*\.js" -type f -ctime +1d -ctime -3d

在我的Linux系统上(使用GNU findutils),-ctime不带单位,只接受表示天数的数字。 - askvictor
根据引用文档所述,更改时间而不是创建时间。 - xeruf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接