89

I need to change the timestamp of about 5000 files.

Typing touch file1.txt, touch file2.txt will take me forever.

Is there a way to do something in the lines of touch -R *?

muru
  • 193,181
  • 53
  • 473
  • 722
Unamata Sanatarai
  • 2,948
  • 2
  • 20
  • 23

2 Answers2

139

You can use find command to find all your files and execute touch on every found file using -exec

find . -type f -exec touch {} +

If you want to filter your result only for text files, you can use

find . -type f -name "*.txt" -exec touch {} +
Melebius
  • 11,121
  • 8
  • 50
  • 77
g_p
  • 18,154
  • 6
  • 56
  • 69
  • 29
    I'd suggest using `-exec`'s `+` terminator (instead of `\;`). This will chain multiple arguments onto each `touch` instance (up to the system argument limit) and will therefore fork out *much* less (and probably be faster). – Oli Feb 01 '15 at 09:53
  • 7
    @g_p ... and for a source see [What is the difference between using '+' and '\;' in -exec command?](http://askubuntu.com/a/558819/283843) – αғsнιη Feb 01 '15 at 16:21
  • 5
    And for a dry run, just leave out the `-exec touch {} +` part, and it'll print to your terminal what it *would* have affected. – Alex Feb 01 '15 at 20:11
  • 7
    Thanks, Although I think 'find' is missing his first parameter. `find . -type f -exec touch {} +` – giltsl Mar 22 '18 at 09:17
  • What if I only want to change the access time, not the modification time? Should it be "find -type f -exec touch -a {} +"? – weeo Apr 18 '18 at 09:05
  • @giltsl g_p's answer works verbatim for me – Scruffy Jan 18 '19 at 02:00
  • This is a nice trick to do. – Jinhua Wang Sep 01 '19 at 11:11
  • 4
    It's worth noting that the man page (Ubuntu 19.10) for `find` suggests it is more secure to use `-execdir` rather than `-exec` as `-execdir` runs each command from the directory in which the `find` result is located. It also says that when invoked from a shell, "[the curly brace pair] should be quoted (for example, '{}') to protect it from interpretation by shells". – Bob Sammers Jan 24 '20 at 21:55
  • 2
    Leaving out `-type f`, it will also affect directories: `find . -execdir touch '{}' +` (also incorporated other improvements as mentioned above) – Christopher Bottoms Apr 22 '22 at 16:39
0

g_p's answer makes the timestamp "now" but if for instance you forgot the cp -p parameter and need to replace timestamps with their originals recursively without recopying all the files. Here is what worked for me:

find /Destination -exec bash -c 'touch -r "${0/Destination/Source}" "$0"' {} \;

This assumes a duplicate file/ folder tree of Source: /Source and Destination: /Destination

  1. find searches the Destination for all files & dirs (which need timestamps) and -exec ... {} runs a command for each result.
  2. bash -c ' ... ' executes a shell command using bash.
  3. $0 holds the find result.
  4. touch -r {timestamped_file} {file_to_stamp} uses a bash replace command ${string/search/replace} to set timestamp source appropriately.
  5. the Source and Destination directories are quoted to handle dirs with spaces.