4

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)
5

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||'
  • Hi thanks! Is it possible to make "*/file.php" go through unlimited directories until it finds file.php? "*/" just go through one right? – user88922 Oct 23 '14 at 15:54
  • 1
    Right. To search the entire directory tree under your current directory (rather than looking only at the first level), type shopt -s globstar, and then change the command in my answer to use **/file.php (with two asterisks). – G-Man Oct 23 '14 at 16:14
  • That would be useful as an option in the answer. – geedoubleya Oct 24 '14 at 8:46
  • @geedoubleya: Done. – G-Man Oct 24 '14 at 13:40
1

Yes it is quite possible.

This will give you files which are modified in last 60 minutes:

$ find /domain -type f -mmin -60

or this will give you files which are sorted by modify time.

$ find /domain -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r

Edit #1

If you have file extensions like you said '.php', add this:

-name '*.php'

And I found this you may want to see it.

Edit #2

Well your last edit gets things harder. But You can use ls -t to last modified directories and if you want to sort by time ls -clRt you could use it and after that you can check files but I'm not sure what you want is possible with any specific command. It's possible with a similiar script (Bash or Perl).

  • Hi Thanks. This doesn't give me a list of directories sorted by the last modified date of file.php does it? – user88922 Oct 23 '14 at 14:39
  • Check edited message, I didn't recognize .php thing. – Vivian Maya Oct 23 '14 at 14:43
  • I've edited my question to clarify. – user88922 Oct 23 '14 at 14:46
1

This does almost exactly what you want, except it leaves off the trailing / on the directory names.

find . -maxdepth 2 -name file1.php -printf '%T@ %h (last modified %Td/%Tm/%TY %Tk:%TM)\n' \
| sort -k 1n | sed 's/^[^ ]* .\///'

Credit where credit is due. This is adapted from shlck's answer here.

Edit: All of my %A should have been %T

0

With zsh:

setopt extendedglob
print -rl -- **/file.php(.om:h)

.om sorts the selected files by mtime and :h removes the trailing path component.
If you want to list mtimes too, you could use zstat:

zmodload zsh/stat
for f (**/file.php(.om))
printf '%s %s\t%s\n' $(zstat -F '%d-%b-%Y %T' +mtime -- $f) ${f:h}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.