简体   繁体   English

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

[英]Unix shell script: Update timestamp on all sub-directories and sub-files, including those with spaces

Here's what I'm trying to achieve. 这就是我想要实现的目标。

I have a directory with over 4200 sub-files/sub-directories, all of which need to be set to a certain timestamp. 我有一个包含超过4200个子文件/子目录的目录,所有这些都需要设置为某个时间戳。

This is a problem because many of them have whitespaces and other weird characters. 这是一个问题,因为它们中的许多都有空格和其他奇怪的字符。

First thing I tried: 我试过的第一件事:

touch $(find .)

Won't work because of the spaces. 由于空间不会起作用。 It will update the timestamps on all files and directories that are space-free, but those that are not, do not receive the new timestamp. 它将更新所有无空间的文件和目录的时间戳,但那些没有空间的文件和目录的时间戳不会收到新的时间戳。 In addition, as one might expected, it creates files in the root directory corresponding to the elements of filenames with spaces. 此外,正如人们所预料的那样,它在根目录中创建与带空格的文件名元素相对应的文件。 So if I have a file somewhere named "One Two Three", 'touch' creates the 3 files, "One", "Two" and "Three" in the root. 因此,如果我有一个名为“One Two Three”的文件,“touch”会在根目录中创建3个文件,“One”,“Two”和“Three”。 This by itself can be remedied by using -c with 'touch', but of course it still won't update the file with the spacey name. 这可以通过使用-c和'touch'来解决,但当然它仍然不会使用spacey名称更新文件。

The second thing I tried was: 我尝试的第二件事是:

for FILENAME in $(find .); do touch -t 201007162310.00 "$FILENAME"; done

But it's the same story. 但这是同一个故事。

I've found a couple of results online, but they're all trying to achieve something differently and so suggest ways that won't work for me. 我在网上找到了几个结果,但他们都试图以不同的方式实现某些目标,因此提出一些对我不起作用的方法。

So now I'm lost. 所以现在我迷路了。 Any ideas? 有任何想法吗?

Is it really not possible to make the 'find' command prepend and append each line with a quotation mark or something? 是否真的不可能使'find'命令前置并在每行附加引号或其他内容?

EDIT: This needs to be done via shell script. 编辑:这需要通过shell脚本完成。 Using Perl, PHP or any other environment will not help. 使用Perl,PHP或任何其他环境都无济于事。 I could easily do this with anything else than Unix shell scripting, but it has to be in a Unix shell script, preferably not a big one. 除了Unix shell脚本之外,我可以轻松地做到这一点,但它必须在Unix shell脚本中,最好不要大。

find . -exec touch -t 201007162310.00 {} +

这是做你想做的最简单,最强大的方法。

find and xargs can be made to communicate using null terminated strings, so you can do findxargs可以使用空终止字符串进行通信,所以你可以这样做

find . -print0 | xargs -0 touch

This will not do exactly what you want, as there will be a number of invocations of touch causing differing times. 这不会完全符合您的要求,因为会有许多touch调用导致不同的时间。 Therefore you can use another file to act as a reference timestamp 因此,您可以使用另一个文件作为参考时间戳

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

A couple of options: 有两种选择:

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

If you do 如果你这样做

ls -b

the -b will cause the filename to be printed out with the escape character '\\' in front of the space. -b将导致文件名打印出空格前面的转义字符'\\'。

Update: I tried this 更新:我试过这个

find . | ls -b | xargs touch

and it seemed to work for my little test case. 它似乎适用于我的小测试用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM