Script for changing modification time of files and directories recursively

7,774

Solution 1

Use find -exec for recursive touch, with command line args for dirs to process.

#!/bin/sh
for i in "$@"; do
    find "$i" -type f -exec touch -r {} -d '+3 hour' {} \;
done

You can run it like this:

./script.sh /path/to/dir1 /path/to/dir2

Solution 2

The correct and complete answer is:

To modify access time only with the "touch" command, you must use "-a" parameter, otherwise the command will modify the modification time too. For example, to add 3 hours:

touch -a -r test_file -d '+3 hour' test_file

From man touch:

Update the access and modification times of each FILE to the current time.

-a                     change only the access time

-r, --reference=FILE   use this files times instead of current time.

-d, --date=STRING      parse STRING and use it instead of current time

So, the file will have access time equal to old access time plus 3 hours. And the modification time will stay the same. You can verify this with:

stat test_file

Finally, to modify access time only to an entire directory and its files and subdirectories, you can use "find" command to traverse the directory and use "-exec" parameter to execute "touch" over each file and directory (just do not filter the search with the "-type f" argument, it'll not affect the directories).

find dir_test -exec touch -a -r '{}' -d '+3 hours' '{}' \;

From man find:

-type c     File is of type c:

            d      directory

            f      regular file

and for -exec:

-exec command ;
          Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to the command until an argument consisting  of  ';'  is  encoun-
          tered.  The string '{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone,
          as in some versions of find.  Both of these constructions might need to be escaped (with a '\') or quoted to protect them from expansion by the shell.   See  the  EXAMPLES
          section  for examples of the use of the -exec option.  The specified command is run once for each matched file.  The command is executed in the starting directory.   There
          are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

Just remember enclose the braces in single quote marks to protect them from interpretation as shell script punctuation. The semicolon is similarly protected by the use of a backslash, though single quotes could have been used in that case also.

Finally, to use it into a shell script like "yaegashi" said:

#!/bin/sh
for i in "$@"; do
    find "$i" -exec touch -a -r '{}' -d '+3 hours' '{}' \;
done

And run it like "yaegashi" said:

./script.sh /path/to/dir1 /path/to/dir2

It'll search through every directory inside both dir1 and dir2 and change only access time for every file and subdirectory.

Share:
7,774

Related videos on Youtube

Achus
Author by

Achus

Updated on September 18, 2022

Comments

  • Achus
    Achus over 1 year

    I have many big folders with thousands of files in them and I want to use touchto set their modification times to be "original time"+3 hours.

    I got this script from a similar thread in superuser:

    #!/bin/sh
    for i in all/*; do
      touch -r "$i" -d '+3 hour' "$i"
    done
    

    so I'm guessing what I need is to make it work in any directory instead of a fixed one (so I won't need to edit the script everytime I want to run it somewhere different) and for it to able to find and edit files recursively.

    I have little experience using Linux and this is my first time setting up a bash script, though I do know a thing or two about programming (mainly in C).

    thanks you all very much for the help :)

    • Celada
      Celada almost 9 years
      Your question title talks about access time but you don't mention access time anywhere else in the body of your question. You mention modification time instead. I took the liberty of editing your question title to match the body.
  • Achus
    Achus almost 9 years
    thanks for replying! So it will search through every directory inside both dir1 and dir2?
  • yaegashi
    yaegashi almost 9 years
    @Achus Yes, that's right.
  • A.B.
    A.B. almost 9 years
    For files and directories, remove the -type switch and only the access time, add the -a switch.