Peter Walker
Peter Walker

Reputation: 3

Batch changing file creation dates in Mac OS Terminal by a set amount of time

Short Backstory

I bought a router and was setting it up. It would seem that when I plugged in my NAS, the router wasn't done getting set up, so the "creation" time for all files present were pushed forward by about 20 years (ie. the router started by assuming that the year was 2000, when it actuality it was late 2020). Anyway, so, I've got a bunch of files that are 10+ years in the future.

Goal

Using Mac OSX's Terminal (which I still have configured to use the bash shell and not zsh), I want to dynamically modify the files with the improper creation dates to remove a set amount of time.

Current Progress

Reading through another SO answer tells me that the following will modify a file's creation date.

touch -t YYYYMMDDhhmm THE_FILE

Through reading some man pages and answers to another SO question, I've got the following command to find all files (within my current directory) with a problematic date.

find . -type f -newermt '1/1/2025 00:00:00'

I also used yet a third SO answer to do some debugging to make sure my date math was correct.

date -r "$(expr $(stat -f %c THE_FILE) - 661361702)" +%Y%m%d%H%M

In my case, the 661361702 was determined to be "20 years 11 months 15 days" in seconds, the length of time since 2000-01-01 00:00:00 to the day I was setting up the router and messed up the dates.

For a set of files matching my criteria with find, I want to use touch to modify the creation date, calculated from the results of stat on the file with a set number of seconds subtracted from each file's current creation date.

I'm trying to stitch this all together and don't know how to correctly use the -exec option of find properly to nest all of these commands into one line.

Upvotes: 0

Views: 1961

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 28985

A bash loop, instead of trying to fit all this in the exec action of find, would probably ease the coding of your script:

find . -type f -newermt '1/1/2025 00:00:00' -print0 | \
while IFS= read -r -d '' f; do
    s=$(stat -f %c "$f")
    (( s -= 661361702 ))
    d=$(date -r "$s" +%Y%m%d%H%M)
    touch -t "$d" "$f"
done

Note: the solution above uses the -print0 option of find and the empty delimiter of read (-d '') to separate the found file names with the NUL character, instead of the default space. This is robust and will work even if you have file names with newlines, tabs, spaces...

Upvotes: 2

Related Questions