这个问题与问题“触摸目录中的所有文件夹”。
如何处理touch
目录中的所有内容,
- 递归地
- 包括隐藏条目,例如“directory up”
..
和.
- 无需取消引用符号链接
touch -h
和 使用参考文件
touch -r <file>
作为时间戳源从一个内shell脚本?
答案1
如果您的touch
命令-h
支持不取消引用:
find . -depth -exec touch -h -r "$reference_file" {} +
touch -c -h -r "$reference_file" ..
(请注意,这-h
意味着-c
(如果 NetBSD/FreeBSD 不存在该文件,则避免创建该文件,但 GNU 或 busybox 不存在该文件touch
(尽管使用 GNUtouch
它也不会创建文件并打印错误消息),因此-c
在此处添加以增加可移植性)。
或者使用单个命令可以减少正在运行的命令find
数量:touch
find .. . -depth \( ! -name .. -o -prune \) -exec touch -c -h -r "$reference_file" {} +
也就是说,添加到..
给定的文件列表中find
,但find
告诉修剪它(而不是下降到其中)。
对于任意目录(路径不以 开头的目录-
:
find "$dir/.." "$dir/" \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" {} +
(这里使用$dir/
代替指代指向目录的符号链接的$dir
情况)。$dir
使用 BSD find
,您可以使用
find -f "$dir/.." -f "$dir/" \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" -- {} +
$dir
以避免以开头的问题-
。
尽管你也可以这样做:
(
cd -P -- "$dir/" &&
exec find .. . \( ! -name .. -o -prune \) \
-exec touch -c -h -r "$reference_file" {} +
)
(假设$reference_file
不是相对路径)。
请注意,如果$reference_file
是符号链接,则使用 GNUtouch
和 with 时-h
,将使用符号链接的修改时间(不使用目标的修改时间-h
),而使用 NetBSD (从哪里来-h
) 和 FreeBSD 中touch
,目标的修改时间可以使用或不使用-h
。
如果使用zsh
,您可以使用它的递归通配符
autoload zargs
zargs -- $dir/{.,..,**/*(NDoN)} -- touch -c -h -r $reference_file --
(oN
可以省略不排序列表,这只是为了优化)。
ksh93 最终在 2005 年添加了对 zsh 递归通配符的支持,并带有该globstar
选项。
(set -o globstar; FIGNORE=
command -x touch -c -h -r "$reference_file" -- ~(N)"$dir"/**)
但请注意,这ksh
将包括此处的所有.
和..
条目,因此所有目录都将被多次触及。
bash 最终在 2009 年复制了 ksh93 globstar
,但最初是 /broken/,因为它在降序目录时遵循符号链接。它于 2014 年在 4.3 中得到修复。
bash 没有相当于 zshzargs
或ksh93
的功能command -x
来分割命令行以避免arg 列表太长问题。在 GNU 系统上,您始终可以使用 GNUxargs
来实现:
xargs -r0a <(
shopt -s dotglob nullglob globstar
printf '%s\0' "$dir/"{.,..,**}
) touch -c -h -r "$reference_file" --
现在,我可能仍然会使用find
这里。除了较差的性能之外,glob 的另一个问题是遍历目录树时的错误(例如访问被拒绝)会被默默地忽略。