I am trying to increase the timestamp of all files in a directory tree by one hour (to correct for DST change). After a lot of tinkering and searching I have figured out how to do it with find, stat and touch, but when I put all together in one command it fails. the command is:
find ~/dir -type f -exec touch -m --date="$(stat -c '%y' '{}') + 3600 sec" '{}' \;
or alternatively using args:
find $DIRNAME -type f -print0 | xargs -0 touch -m --date="$(stat -c '%y' '{}') + 3600 sec"
however it does not work and returns an error: stat: cannot stat `{}': No such file or directory
I have been banging my head on this wall for half a day now. Any s开发者_StackOverflow社区uggestion?
find $DIRNAME -type f |
while read file; do
touch -m --date="$(stat -c '%y' "$file") + 3600 sec"
done
The error message from your second example was because you didn't use xargs -I {}
. In order to avoid things being evaluated prematurely, pass the command to sh
in single quotes.
find $DIRNAME -type f -print0 | xargs -0 -I {} sh -c 'touch -m --date="$(stat -c '%y' "{}") + 3600 sec" "{}"'
Thanks a lot, chris! Actually there should be a "$file" at the end (with the quotes or it will ignore filenames with spaces, not sure why), but other than that it seems to work.
find $DIRNAME -type f |
while read file; do
touch -m --date="$(stat -c '%y' "$file") + 3600 sec" "$file"
done
Try this:
find . -type f | while read line; do NEW_TS=`date -d@$((\`stat -c '%Y' $line\` + 3600 )) '+%Y%m%d%H%M.%S'`; touch -t $NEW_TS ${line}; done
This will do it
find $DIRNAME -type f -exec bash -c 'touch -m --date="$(stat -c %y "$1") + 3600 sec" "$1"' -- {} \;
The problem is that -exec has a hard time locating {}, sometimes, and if your -exec uses + instead of \; it only allows it once. In cases like this sometimes the "easiest" thing is to invoke bash and pass it each result, which is what I'm doing above.
All this really accomplishes in this case is to avoid the read/while loop of other solutions, but in some cases it's an essential technique.
I am the original poster. Thank you all for the tips and the explanations. Just to clarify why I am doing this. The DST change has affected a FAT external hard drive I use to transfer data between windows, mac and linux systems and so screwed up my rsync. I thought it would be easier and faster to change the atime of all files than to copy everything over (maybe not, but that's for another thread, I guess)
精彩评论