简体   繁体   中英

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.

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. 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.

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?

EDIT: This needs to be done via shell script. Using Perl, PHP or any other environment will not help. 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.

find . -exec touch -t 201007162310.00 {} +

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

find and xargs can be made to communicate using null terminated strings, so you can do

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. 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 find . | while read x; do touch $x; done
  • Use xargs , like this 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.

Update: I tried this

find . | ls -b | xargs touch

and it seemed to work for my little test case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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