查找最近修改的文件的Bash脚本

4
我有两个文件夹,假设是 /Volumes/A 和 /Volumes/B。它们是从 Windows 服务器挂载的网络共享,包含来自 Backup Exec 的大量 .bkf 文件。
我正在寻找一个脚本,它将查找这两个文件夹中最近修改的 .bkf 文件,并将其复制到另一个位置。文件夹中还有其他必须被忽略的文件。
谢谢您的帮助!
Shaun
编辑:
我整理了一下代码:
cp ls -alt /Volumes/E /Volumes/F| grep bkf | head -n 1 | awk '{print $8}' /Volumes/$xservedisk/Windows/ 

有人能想到为什么我不应该使用它吗?

再次感谢 肖恩

5个回答

5

我更喜欢使用以下方法来查找最近修改过的文件:

find . -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort

这样的做法有递归的缺点。 - Plasma

4
NEWEST=
for f in /Volumes/A/*.bkf /Volumes/B/*.bkf
do
    if [ -z "$NEWEST" ]
    then 
        NEWEST=$f
    elif [ "$f" -nt "$NEWEST" ] 
    then
        NEWEST=$f
    fi
done

或者将整个代码块折叠成 [ -n "$NEWEST" ] && [ "$NEWEST" -nt "$f" ] || NEWEST=$f,但我认为这是个人口味问题。 - ephemient
这是最好的解决方案,因为我需要文件的完整路径。谢谢你,道格拉斯! - Shaun Johnson

2

为了确保处理奇怪字符的文件名,需要进行一些曲折的操作,而mouviciel的方法则不行:

NEWEST=$(find /Volumes/A /Volumes/B -name '*.bkf' -printf '%T@ %p\0' | \
    sort -rnz | xargs -0n1 2>/dev/null | head -n1 | cut -d' ' -f2-)
[[ -n "$NEWEST" ]] && cp -v "$NEWEST" /other-location

实际上,由于这些文件来自Windows,因此它们的名称几乎可以保证不会包含奇怪的字符(例如嵌入的换行符)。

NEWEST=$(find /Volumes/A /Volumes/B -name '*.bkf' -printf '%T@ %p\n' | \
    sort -rn | head -n1 | cut -d' ' -f2-)
[[ -n "$NEWEST" ]] && cp -v "$NEWEST" /other-location

你为什么选择使用空终止符? - Jé Queue
包含换行符的文件名可能会使“sort”出现问题。当然,如果找到的第一个文件确实带有嵌入换行符,那么“head”也不会完全正确。 - ephemient
感谢您提供的出色答案。在打开这个问题后,我创建了以下代码。这种方式有什么问题吗?cp ls -alt /Volumes/E /Volumes/F| grep bkf | head -n 1 | awk '{print $8}' /Volumes/$xservedisk/Windows/再次感谢。 - Shaun Johnson
不支持处理带有空格或其他奇怪字符的文件名。 - ephemient

2

查找文件的命令是:find /Volumes/[AB] -name '*.bkf'

按修改时间排序文件的命令是:ls -t

如果文件数量不多,可以简单地使用:

ls -lrt `find /Volumes/[AB] -name '*.bkf'`

最后显示的文件是最近修改过的。

编辑

一种更为健壮的解决方案(感谢 ephemient)是:

find /Volumes/[AB] -type f -name '*.bkf' -print0 | xargs -0 ls -lrt

2
在包含空格或其他奇怪字符的任何名称上失败。 - ephemient
这就是为什么我点赞了你的回答。我的回答可能对大多数老派用户来说已经足够了。 - mouviciel
你可以通过 find -print0 | xargs -0 ls -ldrt 来解决这个问题(在某些白痴创建了一个名为 *.bkf 的目录时使用 -d),但这仍然存在解析问题的问题... - ephemient
我可以使用 find -type f 过滤掉 *.bkf 目录。感谢您的建议。 - mouviciel

1
cp `find /Volumes/[AB] -name '*bkf' -type f -printf "%A@\t%p\n" |sort -nr |head -1 |cut -f2` dst_directory/

1
不错,但你应该按修改时间而不是访问时间排序,并且如果路径名包含空格,则会失败(尽管你几乎做对了),cp不能仅使用一个参数。 - ephemient
在NFS挂载中,访问可能会受到限制,但应该考虑其他时间。是的,cp是我的打字错误,我已经编辑过了。文件名可以有空格吗?开个玩笑,用双引号解决这个问题。 - Jé Queue
...啊,现在我明白你的cut -f2-了。 - Jé Queue

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