Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change date modified of multiple folders to match that of their most recently modified file

I've been using the following shell bin/bash script as an app which I can drop a folder on, and it will update the date modified of the folder to match the most recently modified file in that folder.

for f in each "$@"
do
    echo "$f"
done
$HOME/setMod "$@"

This gets the folder name, and then passes it to this setMod script in my home folder.

#!/bin/bash
# Check that exactly one parameter has been specified - the directory
if [ $# -eq 1 ]; then
   # Go to that directory or give up and die
   cd "$1" || exit 1
   # Get name of newest file
   newest=$(stat -f "%m:%N" * | sort -rn | head -1 | cut -f2 -d:)
   # Set modification date of folder to match
   touch -r "$newest" .
fi

However, if I drop more than one folder on it at a time, it won't work, and I can't figure out how to make it work with multiple folders at once.

Also, I learned from Apple Support that the reason so many of my folders keep getting the mod date updated is due to some Time Machine-related process, despite the fact I haven't touched some of them in years. If anyone knows of a way to prevent this from happening, or to somehow automatically periodically update the date modified of folders to match the date/time of the most-recently-modified file in them, that would save me from having to run this step manually pretty regularly.

like image 870
Max Well Avatar asked Dec 05 '25 14:12

Max Well


1 Answers

The setMod script current accepts only one parameter. You could either make it accept many parameters and loop over them, or you could make the calling script use a loop.

I take the second option, because the caller script has some mistakes and weak points. Here it is corrected and extended for your purpose:

for dir; do
    echo "$dir"
    "$HOME"/setMod "$dir"
done

Or to make setMod accept multiple parameters:

#!/bin/bash

setMod() {
   cd "$1" || return 1
   # Get name of newest file
   newest=$(stat -f "%m:%N" * | sort -rn | head -1 | cut -f2 -d:)
   # Set modification date of folder to match
   touch -r "$newest" .
}

for dir; do
   if [ ! -d "$dir" ]; then
       echo not a directory, skipping: $dir
       continue
   fi

   (setMod "$dir")
done

Notes:

  • for dir; do is equivalent to for dir in "$@"; do
  • The parentheses around (setMod "$dir") make it run in a sub-shell, so that the script itself doesn't change the working directory, the effect of the cd operation is limited to the sub-shell within (...)
like image 73
janos Avatar answered Dec 07 '25 06:12

janos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!