0

I use ls -t * | head -n1 (in the OS X bash shell) to identify the most recently modified file in a working directory. How would I write the command to also iterate through subdirectories? What I am looking for is the last modified file anywhere in the working directory, including in subdirectories.

The post How can I list (ls) the 5 last modified files in a directory? and others like it do not address iterating through subdirectories--that's the specific issue I'm trying to solve here.

Community
  • 1
  • 1
misterjoff
  • 13
  • 6
  • Since this doesn't directly involve programming (doesn't look like this is intending to discuss shell scripting, just some small commands), this question is better suited for [superuser](http://superuser.com/) or perhaps [Linux/Unix](http://unix.stackexchange.com/). –  Jun 08 '16 at 20:46

3 Answers3

0

Try ls -ltR --time-style=+%s DIRECTORY_HERE/ | grep -oP " [0-9]{10}[ ].*$" | sort -r | cut -c 13- | head -n1

Breaking it down, the command says:

  1. ls -ltR --time-style=+%s DIRECTORY_HERE/

List all files and folders recursively, along with the time and other information. List the time as a UNIX timestamp.

  1. grep -oP " [0-9]{10}[ ].*$"

Feed that result into grep, and have grep match and print only the filename and the UNIX timestamp. Note that this wont work with filenames that have 10 consecutive digits

  1. sort -r

Reverse sort the list of files. As UNIX timestamp is the first part of every line, it will be sorted most recent first.

  1. cut -c 13-

Keep only the filename (cut out the timestamp and newline characters).

  1. head -n1

Print the first (most recent) filename

neallred
  • 740
  • 1
  • 8
  • 24
  • Thank you for this... I am getting an error `ls: illegal option -- -` and then `usage: ls ...` and `usage: grep ...` – misterjoff Jun 08 '16 at 22:17
  • I think there's a couple things. 1. I'm using Linux bash shell, and it looks like options for ls are different on OS X bash shell. For the first command, you need to print a UNIX timestamp. I'm not sure how to do that in OS X. 2. It looks like the grep options allowed are also different. I'm not sure which one, but I'd guess it's complaining about the -P option for grep. – neallred Jun 08 '16 at 22:50
  • For adjusting the grep command, there's an answer to that here: http://stackoverflow.com/questions/16658333/grep-p-no-longer-works-how-can-i-rewrite-my-searches – neallred Jun 08 '16 at 22:59
0

why not find ?

find -printf "%T@ %p\n" | sort -n | tail -1
  • find all files in current directory and sub directories and print two fields for each file

    %T@ File's last modification time in seconds with fractional part

    %p File's name

  • numeric sort on first field

  • last record will be the latest modified file.

ppp
  • 975
  • 7
  • 15
  • Find is a fine alternative, but I'm using the OS X bash shell and FreeBSD no longer supports `-printf`. I've tried some of the suggestions at [find lacks the option -printf, now what?](http://stackoverflow.com/questions/752818/find-lacks-the-option-printf-now-what) but have not been successful in making this work. – misterjoff Jun 09 '16 at 14:41
0

You may want to use ls -ltr to list files by modification time in reversed order (long listing format) and tail -1 to print only last line of output.

ls -ltr | tail -1

Or ls -1tr to print only one column of output.

ls -1tr | tail -1

I suggest to use r option (that is "in reversed order") since if you have lots of files to list you most likely want to see most recently modified files at the bottom rather than at the top of screen.

To search recursively in current working directory:

find . -maxdepth 1 -type d -exec ls -ltr {} +

or just

ls -lrtR

To get only the directory name and most recently modified file in it:

find . maxdepth 1 -type d | while read PATH; do
    printf "%s: %s\n" ${PATH} $(ls -1tr | tail -1)
done