Here is how to change directory timestamps to match the latest file modification timestamp in that directory (or subdirectory timestamp if there are no files in the directory), for current working directory and all subdirectories.
Code:
find . -depth -type d -print0 | while read -rd "" dir ; do
last=$(find "$dir" -maxdepth 1 -type f -printf '%TY%Tm%Td%TH%TM-%TS\n' | sed -e 's|\..*$||g' -e 's|-|.|' | sort -rg | sed -ne '1 p')
[ -n "$last" ] || last=$(find "$dir" -maxdepth 1 -printf '%TY%Tm%Td%TH%TM-%TS\n' | sed -e 's|\..*$||g' -e 's|-|.|' | sort -rg | sed -ne '1 p')
[ -n "$last" ] && echo touch -t "$last" "$dir"
done
If you run the above, it will only show the touch commands it would run; it will not actually run them. It is a good idea to check first. As it uses ASCII NUL (zero byte) as a separator, it will work correctly for all possible file and directory names in Linux, including those that contain spaces, newlines, or control characters.
If you use UTF-8, and some of your file names contain invalid UTF-8 sequences (are for example in some other character set), run
Code:
export LANG=C LC_ALL=C
before running the snippet above, to make sure character set issues are ignored. (This selects the POSIX locale. Some tools will abort when they see invalid UTF-8 sequences; using the POSIX locale tells them to only consider ASCII letters, and not try to parse UTF-8 sequences at all, just keep them intact.)
When the scriptlet works for you, just drop the
echo and rerun it to apply the time stamp changes.
The script was tested using GNU find 4.4.2, GNU sed 4.2.1, sort and touch from GNU coreutils 8.5, and Bash 4.1.5.