【问题标题】:How to find files older than N days from a given timestamp如何从给定的时间戳中查找超过 N 天的文件
【发布时间】:2012-06-30 04:03:39
【问题描述】:

我想从给定的时间戳中查找超过 N 天的文件,格式为 YYYYMMDDHH

我可以使用以下命令找到超过 2 天的文件,但这会找到当前时间的文件:

find /path/to/dir -mtime -2 -type f -ls

假设我输入 timestamp=2011093009 我想查找距 2011093009 超过 2 天的文件。

一直在研究,但似乎无法弄清楚。

【问题讨论】:

  • 递归?当前目录?
  • 是的,递归../path/to/dir 下的所有文件
  • 查找超过 2 天的命令是否应该是 find /path/to/dir -mtime +2 -type f -ls?我试过这个,在我的系统(xubuntu,bash)上,-2 选项 -mtime 会找到 2 天以上的文件。
  • 我不喜欢 -mtime 因为我觉得它太“相对”了。对于更“绝对”的解决方案,尝试“touch -t”创建具有相关时间戳的文件,然后找到“-newer”和“!”运营商。

标签: shell unix find ksh


【解决方案1】:
#!/usr/bin/env bash

# getFiles arrayName olderDate newerDate [ pathName ]
getFiles() {
    local i
    while IFS= read -rd '' "$1"'[(_=$(read -rd "" x; echo "${x:-0}")) < $2 && _ > $3 ? ++i : 0]'; do 
        :
    done < <(find "${4:-.}" -type f -printf '%p\0%Ts\0')
}

# main date1 date2 [ pathName ]
main() {
    local -a dates files
    local x
    for x in "${@:1:2}"; do
        dates+=( "$(date -d "$x" +%s)" ) || return 1
    done

    _=$dates let 'dates[1] > dates && (dates=dates[1], dates[1]=_)'
    getFiles files "${dates[@]}" "$3"
    declare -p files
}

main "$@"

# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:

这个 Bash 脚本需要两个日期和一个find 的路径名。 getFiles 采用数组名称,两个日期之间有 mtimes 的文件被分配给该数组。此示例脚本仅打印数组。

需要最近的 Bash 和 GNU 日期。如果它真的必须是“N 天”,或者你没有 GNU 日期,那么就没有可能的解决方案。您需要使用不同的语言。没有任何 shell 可以使用标准实用程序来做到这一点。

从技术上讲,您可以使用printf '%(%s)T' ... 和一些算术计算以天为单位的偏移量,但是没有可能的方法可以从没有 GNU 日期的时间戳中获取基准日期,所以恐怕您不走运。

编辑

我看到这个问题有一个 ksh 标签,在这种情况下我撒了谎,显然 ksh93 的 printf 接受一个 GNU date -d 之类的字符串。我不知道它是否便携,当然需要安装 ksh93 的系统。在这种情况下,您可以对上述脚本进行一些修改。

【讨论】:

  • 感谢您的回复...不幸的是,我的系统没有 GNU 日期,所以-d 不是一个选项...但是,经过更多研究,我已经找到了一个回答我的问题。你可以看看我接受的答案
  • 是的,没关系,我在完成此操作时注意到您的其他 cmets。无论如何,我希望有人觉得它有用。
【解决方案2】:

这基本上是通过查找一系列日期中的文件来完成的...

我使用 perl 计算从今天到给定时间戳的天数,因为 GNU 日期在我的系统中不可用,所以 -d 不是一个选项。下面的代码接受格式为 YYYYDDMM 的日期。见下文:

#!/usr/bin/perl 
use Time::Local;

my($day, $month, $year) = (localtime)[3,4,5];
$month = sprintf '%02d', $month+1;
$day   = sprintf '%02d', $day;
my($currentYear, $currentDM) = ($year+1900, "$day$month");
my $todaysDate = "$currentYear$currentDM";
#print $todaysDate;

sub to_epoch {
    my ($t) = @_;  
    my ($y, $d, $m) = ($t =~ /(\d{4})(\d{2})(\d{2})/); 
    return timelocal(0, 0, 0, $d+0, $m-1, $y-1900);
}
sub diff_days {
    my ($t1, $t2) = @_;  
    return (abs(to_epoch($t2) - to_epoch($t1))) / 86400; 
}
print diff_days($todaysDate, $ARGV[0]);

**注意:我不是 Perl 专家,这是我修改/编写的第一段代码。话虽如此,我确信在 Perl 中有更好的方法来完成上述操作

然后是下面的 korn 脚本来执行我需要的操作。

#!/bin/ksh
daysFromToday=$(dateCalc.pl 20110111)
let daysOld=$daysFromToday+31
echo $daysFromToday "\t" $daysOld

find /path/to/dir/ -mtime +$daysFromToday -mtime -$daysOld -type f -ls

我正在查找所有早于+$daysFromToday 的文件,然后将搜索范围缩小到比-$daysOld 新的天数

【讨论】:

    【解决方案3】:

    输入答案之一from here 并按照建议使用 $() here

    (根据 sputnick 的评论更新)

    date=2011060109; find /home/kenjal/ -mtime $(( $(date +%Y%m%d%H) - $(date -d $date +%Y%m%d%H) ))
    

    【讨论】:

    • expr 是旧时尚 ;) date=2011060109; find /home/kenjal/ -mtime $(( $(date +%Y%m%d%H) - $(date -d $date +%Y%m%d%H) ))
    • 这当然需要 GNU 日期(-d 选项不可移植)。另外,我认为这不能解决原始问题;他想要从某个日期开始超过 N 天的文件。不知道自己该怎么做...
    • Bob Duell:你说得对,我想要从某个日期开始超过 N 天的文件。是的,我没有 GNU 日期,所以 -d 选项对我不起作用
    • kinjal:谢谢你的回答,你提供的链接引导我得到正确的答案,花了我一些时间,但终于明白了:)。一会儿我会发...
    猜你喜欢
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 2013-09-22
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多