5

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
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
rubo77
  • 28,966

3 Answers3

5

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 Full directories).

3

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.

Flup
  • 8,145
  • this 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 – bestestefan Dec 20 '19 at 12:03
2

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.

camh
  • 39,069