Unix shell脚本:更新所有子目录和子文件的时间戳,包括带有空格的文件

3

以下是我想要实现的目标。

我有一个包含4200多个子文件/子目录的目录,所有这些文件/目录都需要设置为特定的时间戳。

这是一个问题,因为其中许多文件名包含空格和其他奇怪字符。

我尝试的第一件事:

touch $(find .)

由于存在空格,该方法无法奏效。它会更新所有没有空格的文件和目录的时间戳,但没有空格的文件不会接收新的时间戳。此外,正如人们所预料的那样,它会在根目录中创建与带有空格文件名元素相对应的文件。因此,如果我在某个地方有一个名为“One Two Three”的文件,“touch”将在根目录中创建3个文件,“One”,“Two”和“Three”。使用“-c”可以解决这个问题,但当然它仍然无法更新具有空格名称的文件。
我尝试的第二件事是:
for FILENAME in $(find .); do touch -t 201007162310.00 "$FILENAME"; done

但是这个问题一直存在。

我在网上找到了几个结果,但它们都试图以不同的方式实现某些东西,因此提出的方法对我来说都行不通。

所以现在我很迷茫。有什么想法吗?

难道真的不能使“查找”命令在每行前面和后面添加引号或其他内容吗?

编辑:必须通过shell脚本完成。使用Perl、PHP或任何其他环境都无济于事。我可以轻松地用除Unix shell脚本之外的任何东西来完成这个任务,但它必须在Unix shell脚本中完成,最好不要太复杂。

4个回答

12
find . -exec touch -t 201007162310.00 {} +

这是实现你想要的功能最简单、最稳定的方法。


谢谢sch,你说得完全正确。我已经修复了它。很遗憾你的编辑被拒绝了。 - Roman Cheplyaka
谢谢。抱歉第一次错过了,但是为了标准化/可移植性,您还需要在 find . -exec ... 中使用 . - Stephane Chazelas
那我不知道。你有参考资料吗? - Roman Cheplyaka
POSIX规范。传统的find命令(如Solaris)会在您的行上返回find: path-list predicate-list错误。 - Stephane Chazelas
我刚刚将答案更正了,因为它简单多了。:) 对此感到有点遗憾,因为我非常欣赏 Beano 的回答,但你的毫无疑问更好。 - Teekin

5

findxargs可以使用空字符终止的字符串进行通信,这样你就可以执行以下操作:

find . -print0 | xargs -0 touch

这种方法不能完全满足您的需求,因为会有多次调用touch导致时间不同。因此,您可以使用另一个文件作为参考时间戳。

touch /tmp/ref
find. -print0 | xargs -0 touch -r /tmp/ref

实际上,我正在使用“touch”上的-t运算符来指定精确的时间。 :) 这很有效,非常感谢! - Teekin

1

有几个选项:

  • 使用read,像这样:find . | while read x; do touch $x; done
  • 使用xargs,像这样:find . -print0 | xargs -0 touch

1
read 更改为 read -r,否则带有反斜杠的文件名将无法工作,而将 touch "$x" 更改为文件名带有空格和通配符 (\[?*) 将无法工作。或者更好的方法是忘记第一个笨拙的解决方案,使用 -print0 (仅限 GNU BSD) 或 find -exec (标准)。 - Gilles 'SO- stop being evil'
下面这个一行命令:"find . | while read x; do touch $x; done" 递归地处理了一些文件,但不是全部的文件!! - user1547624

0
如果你这样做
ls -b

-b选项会导致文件名在空格前面加上转义字符'\'并打印出来。

更新:我尝试了这个方法。

find . | ls -b | xargs touch

对于我的小测试案例来说,它似乎是有效的。


对于这个特定的问题并没有什么帮助,但知道这一点还是挺好的,+1 :) - Teekin
Helgi,不知道你是否会收到我的答案编辑通知,所以我添加了这个评论。 - Chance
1
ls 不会解析其标准输入,因此它不会递归进入目录。 ls -b 为非可打印字符打印八进制转义(xargs 不解析它们),并保留 '"(因此 xargs 将尝试解析它们)。 这是一个例子,说明你不应该解析 ls 的输出 - Gilles 'SO- stop being evil'
我改正了。事实上,我的代码只适用于当前目录中的文件。我的错误。 - Chance

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