如何在 bash 脚本中比较日期

如何在 bash 脚本中比较日期

我正在尝试在 bash 中编写一个脚本来确定文件结构中最旧的目录。

在此示例中,我有四个目录,其标题模仿了它们的创建日期和时间。这些文件是2022-02-21:20:30:232022-02-21:22:30:232022-02-28:22:30:232023-02-28:22:30:23。在本例中,日期是任意的,并且只是为了测试脚本而开发的。

我希望脚本能够识别该目录中存在的目录,并根据目录的名称来识别哪个是最旧的目录。

我最初的尝试如下所示,是的,我知道字符串没有正确声明为日期,但我不知道如何做到这一点,并且可以使用一些建议。

oldest="1899-01-01:01:01:01"
dirs=`ls -d */`
for i in $dirs ; do
    if [[ oldest < $i  ]] ; then
        oldest=$i
    fi
done
echo $oldest

答案1

(我假设您显示的命名约定是用于您的命名约定目录并且您想要找到最旧的目录。我忽略了文件在这些目录中。)

根据您的命名约定,您的目录名称会通过扩展 shell glob 自动正确排序,*/以便最旧的目录名称在扩展中排在第一位。默认情况下,shell 会按字典顺序为您提供匹配的名称。

这意味着您可以通过扩展*/通配模式(假设它完全匹配任何内容)、将结果存储在数组中并查看该数组的第一个和最后一个元素来获取最旧和最新的目录:

dirs=( */ )
printf 'Oldest dir by name is "%s"\n' "${dirs[0]}"
printf 'Newest dir by name is "%s"\n' "${dirs[-1]}"

请注意上面的“最旧/最新的名称”实际上意思是“按字典顺序排序第一个/最后一个”。

您想要删除/输出的目录路径的尾部,请使用标准参数替换:

dirs=( */ )
printf 'Oldest dir by name is "%s"\n' "${dirs[0]%/}"
printf 'Newest dir by name is "%s"\n' "${dirs[-1]%/}"

答案2

如果文件名都是这种YYYY-MM-DD:HH:MM:SS格式,并且文件名很重要,那么您可以按字典顺序对它们进行排序。例如,这应该是名称最旧的文件夹:

printf "%s\n" */ | sort | head -n1

答案3

文件名总是采用这种形式吗YYYY-mm-dd:HH:MM:ss?如果是这样,那就更容易了,因为我们只需要处理数字。使用sort,就像 @muru 已经提到的那样,将是最直观的方式。像这样:ls -d --format=single-column */ | sort | head -n 1

如果想使用修改日期,可以ls直接使用:

ls -dt --format=single-column */ | head -n 1 # most recent modification date
ls -dt --format=single-column */ | tail -n 1 # oldest modification date

-d:仅显示目录; -t:按日期排序,最新的在前; single-column:仅显示(文件)名称; */:过滤目录

经典if a < b; then min = b循环是 bash 中查找集合中最大/最小数的默认方法。但你也可以翻译日期使用 字符串转换为数字date,这允许您使用 bash 内置函数[ .. -t .. ]。虽然这不适用于您的具体情况-由于第一个冒号 (YYYY-mm-dd HH:MM:SS),date无法解析此处时间的日期。:

# mind the space ---v
filename='1989-06-08 12:42:00'
number=$(date -d "$filename" '+%s'))
# 'date' values can directly be compared:
now=$(date '+%s')
if [ number -lt  now ]; then
  echo $(date -d "number") was in the past.
else
  echo $(date -d "number") is in the future.
fi
  

相关内容