For example, say, I know that my time-offsets are off by several hours (perhaps because my system clock was a few hours ahead at a certain time). In that case, how would I mass-change the "last modified" dates of all the files in a particular directory?

Note that different files will need to have their modification time changed to different values.


If you want to apply a relative offset to the modification time of a file, you can do it with a combination of touch(1) and stat(1). touch supports relative times, but they are relative to now, not the current time on a file. Instead you can use stat to get the current modification time and apply an offset.

For example, to apply a -2 hour offset to the modification time of a file:

touch -m -d @$(( $(stat -c %Y file.txt) - 7200 )) file.txt

stat -c %Y file.txt gets the modification time of file.txt as seconds since the epoch. Using bash arithmetic expansion, you can perform calculations, which in this case is to subtract 7200 seconds (2 hours). Using touch with -m to change the modification time and -d to specify a date, you can set the modification time to what was calculated. The @ is a time format specifier that says the given time is in seconds since the epoch.

If you put this into a shell script, you can call it from find or xargs letting you use find to select the files you want to change.

for file ; do
    touch -m -d @$(( $(stat -c %Y "$file") - 7200 )) "$file"

That will apply the change to the modification time of all files passed as arguments.

| improve this answer | |
  • Does for file without an in clause imply in "$*"? – killermist Jun 23 '12 at 1:26
  • 1
    @killermist: Almost. An absent in clause means in "$@" - i.e. it iterates over the positional parameters. – camh Jun 23 '12 at 3:28
  • 1
    Ah. That is the variable I was looking for. I'm not great at remembering bash's expansion variables. Having more reason to forget them is indirectly encouraging. – killermist Jun 23 '12 at 4:03

Modify one file by hand to the right time (using touch ... TEMPLATE).

Then change the rest by referencing that file (using touch -r TEMPLATE TARGET).

| improve this answer | |
  • This sets all files to the date of that one file, which is not what the question asked. – Gilles 'SO- stop being evil' Jun 23 '12 at 0:58
  • @Gilles it is not clear if setting a unique time is not enough to solve this "problem". If the target is just not to have any files in the future - very fast - this solution is probably better than wasting many operations per file. This is just another solution for a mass time-change. – Nils Jun 23 '12 at 20:27
  • “perhaps because my system clock was a few hours ahead at a certain time”. Your solution does not work (and cannot be easily modified to work) in the example use case that was mentioned in the question. – Gilles 'SO- stop being evil' Jun 23 '12 at 22:16
touch -m -r file.txt -d '-1 hour' file.txt
| improve this answer | |
  • You should explain what you are doing with this command and why. – Raphael Ahrens Mar 31 '14 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.