坚持从目录列表中查找最新文件

坚持从目录列表中查找最新文件

我想找到目录列表,然后在其中搜索给定文件,然后选择最新的文件。

这就是我尝试的:

find /Temp -type d -name Ast 2>/dev/null | while read Dir; do find $Dir -type f -name Pagination.json 2>/dev/null -exec ls -lt {} +; done

这确实给我带来了预期的文件,但它按升序对它们进行排序。

这是该命令的结果:

-rw-r--r-- 1 root root 46667 Sep 12 18:10 /Temp/ProjectOne/Site/Ast/BaseComponents/Pagination.json
-rw-r--r-- 1 root root 46667 Sep 13 09:31 /Temp/ProjectTwo/Site/Ast/BaseComponents/Pagination.json

在这种情况下,我需要第二项。我应该怎么办?

答案1

我解决这个问题的方法是使用 shell 自己的文件查找功能来查找所有候选者,然后保留最新的:

#!/bin/bash

# enable ** as recursive glob, don't fail when null matches are found, and
# also look into things starting with .
shopt -s globstar nullglob dotglob


newestmod=0
for candidate in **/Ast/**/Pagination.json ; do
    # check file type:
    [[ -f ${candidate} ]] || continue
    [[ -L ${candidate} ]] && continue
    # Get modification time in seconds since epoch without fractional
    # part. Assumes GNU stat or compatible.
    thisdate=$(stat -c '%Y' -- "${candidate}")
    
    # if older than the newest found, skip 
    [[ ${thisdate} -lt ${newestmod} ]] && continue
    
    newestmod=${thisdate}
    newestfile="${candidate}"
done

if (( newestmod )); then
  printf 'Newest file: "%s"\n' "${newestfile}"
fi

或诸如此类。

在 中zsh,整个事情变得不那么复杂,并且支持时间戳的亚秒精度:

#!/usr/bin/zsh

#get the list of regular (`.`) files, `o`rdered by `m`odification date
allcandidates=(**/Ast/**/Pagination.json(ND.om))
if (( $#allcondidates )) print -r Newest file: $allcandidates[1]

要不就:

print -r Newest file: **/Ast/**/Pagination.json(D.om[1])

请注意,虽然**/在 zsh 和 bash5.0+ 中,递归遍历目录树时不遵循符号链接,但该Ast/部分将遍历符号链接。如果这是一个问题,在 中zsh,您可以通过以下方式解决它:

set -o extendedglob
print -r Newest file: ./**/Pagination.json~^*/Ast/*(D.om[1])

where./**/Pagination.json查找所有文件而不遍历符号链接,但~pattern删除与模式匹配的路径,这里是不 ( ^) 包含/Ast/.

答案2

它会根据您所说的“最新”的确切含义而略有变化,但是只要 GNU 实现find可用,并且如果我们知道不存在包含换行符的文件路径,我会使用类似以下内容的内容:

find /tmp -type f -printf "%T@ %p\n" | sort -rn

(调整/tmp -type f以找到您真正关心的文件,它可能会类似于find /Temp -path '*/Ast/*' -type f -name 'Pagination.json')。有趣的部分是%T@打印文件自纪元以来的最后修改时间(以秒为单位),这很容易排序。

相关内容