Sorting directories by last modified date/time of the same-named contained file

command linefileslssorttimestamps

Is it possible, using grep, find, etc, to sort a list of directories by the last modified date of the same-named file (e.g., file.php) within? For example:

domain1/file.php (last modified 20-Jan-2014 00:00)
domain2/file.php (last modified 22-Jan-2014 00:00)
domain3/file.php (last modified 24-Jan-2014 00:00)
domain4/file.php (last modified 23-Jan-2014 00:00)

Each directory has the same file name (e.g., file.php).

The result should be:

domain3/ (last modified 24-Jan-2014 00:00)
domain4/ (last modified 23-Jan-2014 00:00)
domain2/ (last modified 22-Jan-2014 00:00)
domain1/ (last modified 21-Jan-2014 00:00)

Best Answer

As Vivian suggested, the -t option of ls tells it to sort files by modification time (most recent first, by default; reversed if you add -r).  This is most commonly used (at least in my experience) to sort the files in a directory, but it can also be applied to a list of files on the command line.  And wildcards (“globs”) produce a list of files on the command line.  So, if you say

ls -t */file.php

it will list

domain3/file.php  domain4/file.php  domain2/file.php  domain1/file.php

But, it you add the -1 (dash one) option, or pipe this into anything, it will list them one per line.  So the command you want is

ls -t */file.php | sed 's|/file.php||'

This is an ordinary s/old_string/replacement_string/ substitution in sed, but using | as the delimiter, because the old_string contains a /, and with an empty replacement_string.  (I.e., it deletes the filename and the / before it — /file.php — from the ls output.)  Of course, if you want the trailing / on the directory names, just do sed 's|file.php||' or sed 's/file.php//'.

If you want, add the -l (lower-case L) option to ls to get the long listing, including modification date/time.  And then you may want to enhance the sed command to strip out irrelevant information (like the mode, owner, and size of the file) and, if you want, move the date/time after the directory name.

This will look into the directories that are in the current directory, and only them.  (This seems to be what the question is asking for.)  Doing a one-level scan of some other directory is a trivial variation:

ls -t /path/to/tld/*/file.php | sed 's|/file.php||'

To (recursively) search the entire directory tree under your current directory (or some other top-level directory) is a little trickier.  Type the command

shopt -s globstar

and then replace the asterisk (*) in one of the above commands with two asterisks (**), e.g.,

ls -t **/file.php | sed 's|/file.php||'