How can I change the date modified of a folder to the last changed file inside?
Solution 1
With zsh
:
cd that-dir &&
touch -r *(D.om[1]) .
If you want to consider files in subdirectories as well:
touch -r **/*(D.om[1]) .
And if you want to do it for every non-empty directory, recursively:
for d (**/*(DFod)) touch -r $d/*(D.om[1]) -- $d
Beware that you'll get "no matches found" errors if there are non-empty directories without regular files (if all the files they contain are non-regular such as directories, symlinks, fifos...). To avoid that, you could change it to:
for d (**/*(DFod)) {
newest=($d/*(ND.om[1]))
(( $#newest )) && touch -r $newest -- $d
}
Remove the .
glob qualifier if you don't want to restrict to regular files, or prefix with -
if you also want to consider symlinks to regular files (and the modification time of the file they point to), or replace with ^/
for non-directory files, or ^/,F
for any type of file except empty directories (non-directories or F
ull directories).
Solution 2
You can set a directory your_dir
's timestamp to that of its most recently modified file with this monstrosity:
touch -t `ls -ltr --time-style='+%Y%m%d%H%M.%S your_dir' | grep '^-' | tail -1 | awk '{print $6}'` your_dir
It's unclear what you mean by 'main folders', so I haven't included any recursion.
Solution 3
Using ls(1)
to order a directory by modification time, head(1)
to get the first of the files, and touch(1)
to change the modification time of your target directory, it's pretty easy.
Usually it is not advisable to parse the output of ls
since it is rarely necessary and easy to be caught up on special characters, however in this case I cannot think of another tool that will as easily give you the file with the latest timestamp in a directory.
touch_dir() {
dir="$1"
touch --reference="$(ls -td -- "${dir}"/* | head -n 1)" -- "${dir}"
}
Run that with an argument that is a directory, and it should set the modification time of the directory to the latest modification time of any file in the directory.
It will fail if there are no files in the directory (easy to test a number of ways) or if the latest filename has an embedded newline - head
will only get the part before the new line.
To update many directories, just run it in a loop.
Related videos on Youtube
Comments
-
rubo77 over 1 year
In my media center directory all modified times of my folders are somehow not the desired date.
How can I change all modified times of the main folders to the modified time of the newest media-file inside each folder?
for example:
cd /tmp mkdir test cd test mkdir d1 mkdir d2 touch d1/text1.txt touch d1/movie1.mov touch d2/text2.txt touch d2/movie2.mov touch notthis.file
now I tried:
ls -td *| head -n 1
but that gives out:
notthis.file
-
Admin almost 11 yearsseems like the other duplicate really explains it already
-
Admin almost 11 yearsIt's closed as a duplicate, you don't need to do anything else
-
Admin over 10 yearsI added my final solution there in that duplicate as an answer: unix.stackexchange.com/a/86730/20661
-
-
Stéphane Chazelas almost 11 yearsNote that it will not consider dot files.
-
enzotib almost 11 yearsto be POSIX, better to use
-r file
instead of--reference=file
-
rubo77 almost 11 yearsthis sounds promising, but It seems not correct. I added an example to my question
-
rubo77 almost 11 yearsmaybe with
find *.mov -maxdepth 0 -type f -printf '%T+=%p\n'
we can get the newest file and use it somehow -
Simon Gates almost 11 yearsYou should never parse the output of
ls
. ;) -
rubo77 over 9 yearsCan you add some explanation of the syntax?
-
Stéphane Chazelas over 9 years
-
bestestefan over 4 yearsthis is exactly what I have been searching for last 30-40 minutes and couldn't find any useful answers related to getting 'real' directory modify time (which in my guess is exactly what your script is extracting), it should be rated higher