如何以递归方式将文件夹时间戳更改为最新文件?

如何以递归方式将文件夹时间戳更改为最新文件?

我想知道是否有人知道如何根据在该文件夹中找到的文件的最新时间戳递归地更改文件夹的时间戳。

例如:

jon@UbuntuPanther:/media/media/MP3s/Foo Fighters/(1997-05-20) 颜色和形状$ ls -alF
总计 55220
drwxr-xr-x 2 乔恩 乔恩 4096 2010-08-30 12:34 ./
drwxr-xr-x 11 乔恩 乔恩 4096 2010-08-30 12:34 ../
-rw-r--r-- 1 jon jon 1694044 2010-04-18 00:51 喷火战机 - Doll.mp3
-rw-r--r-- 1 jon jon 3151170 2010-04-18 00:51 喷火战机 - 足够的空间.mp3
-rw-r--r-- 1 jon jon 5004289 2010-04-18 00:52 喷火战机 - Everlong.mp3
-rw-r--r-- 1 jon jon 5803125 2010-04-18 00:51 喷火战机 - 二月之星.mp3
-rw-r--r-- 1 jon jon 4994903 2010-04-18 00:51 Foo Fighters - 嘿,约翰尼公园!.mp3
-rw-r--r-- 1 jon jon 4649556 2010-04-18 00:52 喷火战机 - Monkey Wrench.mp3
-rw-r--r-- 1 jon jon 5216923 2010-04-18 00:51 喷火战机 - 我的英雄.mp3
-rw-r--r-- 1 jon jon 4294291 2010-04-18 00:52 Foo Fighters - 我可怜的大脑.mp3
-rw-r--r-- 1 jon jon 6778011 2010-04-18 00:52 喷火战机 - New Way Home.mp3
-rw-r--r-- 1 jon jon 2956287 2010-04-18 00:51 Foo Fighters - 再见.mp3
-rw-r--r-- 1 jon jon 2730072 2010-04-18 00:51 Foo Fighters - Up in Arms.mp3
-rw-r--r-- 1 jon jon 6086821 2010-04-18 00:51 Foo Fighters - 追随你.mp3
-rw-r--r-- 1 jon jon 3033660 2010-04-18 00:52 Foo Fighters - Wind Up.mp3

文件夹“(1997-05-20) The Color and The Shape”的时间戳将设置为 2010-04-18 00:52。

答案1

您可以touch -r使用另一个文件的时间戳而不是当前时间(或touch --reference=FILE

这里有两个解决方案。在每个解决方案中,第一个命令将目录的修改时间更改为紧接其下的最新文件的修改时间,第二个命令递归地查看整个目录树。cd '.../(1997-05-20) The Colour and The Shape'在运行任何命令之前更改到目录 ( )。

在 zsh 中(删除D以忽略点文件):

touch -r *(Dom[1]) .
touch -r **/*(Dom[1]) .

在 Linux 上(或者更一般地使用 GNU find):

touch -r "$(find -mindepth 1 -maxdepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .
touch -r "$(find -mindepth 1 -printf '%T+=%p\n' |
            sort |tail -n 1 | cut -d= -f2-)" .

但请注意,这些假设文件名中没有换行符。

答案2

如果要更新当前目录及其子目录中的所有时间戳到当前时间:

find . -exec touch {} \;

答案3

这不是“递归”,它只是更改文件夹中的所有时间戳。如果这就是您的意思,那么有两个步骤。

stat -c '%Y' filename将输出 的时间戳filename,并将stat -c '%Y %n' *输出文件夹中每个文件的时间戳和文件名,因此这将找到当前文件夹中最近修改的文件的文件名:

mostrecent="`stat -c '%Y %n' * | sort -n | tail -n1 | cut -d ' ' -f '2-'`"

再想一想,有一个方式获取文件夹中最高时间戳的更简单方法:

mostrecent="`ls -t | head -n1`"

然后您想要更改文件夹中的所有文件,使其具有与该文件相同的时间戳。touch -r foo bar将更改为bar具有与 相同的修改时间戳foo,因此这会将文件夹中的所有文件更改为与最近修改的文件具有相同的修改时间戳:

touch -r "$mostrecent" *

所以,一行是:

touch -r "`ls -t | head -n1`" *

答案4

我已经采用了 @Gilles zsh 命令并增强了它在子文件夹中的工作,但似乎 zsh 对于 **/*(FDod) 部分效率非常低。

# Don't do this
for d in **/*(FDod); do touch -r "$d"/*(Dom[1]) -- "$d"; done

引号允许包含空格和制表符的目录条目正常工作。 FD 使其查找非空目录,包括以 . 开头的目录,od 使其在深度优先方式,以便父文件夹时间戳得到正确更新。

测试时,我注意到 **/*(FDod) 的性能和内存占用非常疯狂(仅 650k 文件夹就超过 1.4GB),并且它在开始触摸文件夹之前读取了全部内容。将其替换为查找/读取后,它变得更快,不会消耗内存,并且几乎可以立即启动。

#! /usr/bin/env zsh
# Do this instead
find "$@" -depth -type d ! -empty -print0 |while IFS= read -r -d ''; do
    touch -r "$REPLY"/*(Dom[1]) "$REPLY"
done

如果您没有在脚本中运行它,请将“$@”替换为您要从中运行它的文件夹。

相关内容