My folder parent has the following content:

A.Folder B.Folder C.File

It has both folders and files inside. B.Folder is newer. Now I just want to get B.Folder, how could I achieve this? I tried this,

ls -ltr ./parent | grep '^d' | tail -1

but it gives me drwxrwxr-x 2 user user 4096 Jun 13 10:53 B.Folder, but I just need the name B.Folder.

  • 1
    use this ls -ltr ./parent | grep '^d' | tail -1| awk '{print $NF}'
    – Baba
    Jun 13, 2014 at 15:36
  • Using awk works, but I want to see if there is a cleaner solution. :)
    – Daniel
    Jun 13, 2014 at 15:44
  • find . -maxdepth 1 -type d | TZ=utc xargs ls -ld --full-time | sort -k 6 Jun 13, 2014 at 16:18

5 Answers 5


Try this:

$ ls -td -- */ | head -n 1

-t options make ls sort by modification time, newest first.

If you want remove /:

$ ls -td -- */ | head -n 1 | cut -d'/' -f1
  • 1
    How to get rid of slash /?
    – Daniel
    Jun 13, 2014 at 15:39
  • This does not work if you are in another folder. I mean ls -td -- ./parent | head -n 1 does not give me the correct results, do I HAVE TO use subshell such as cd ./parent every time and execute this command? Any solution?
    – Daniel
    Jun 13, 2014 at 16:02
  • @Daniel: You must run my answer in current working directory to make it works. Otherwise, you must use a relative path like Herson's answer.
    – cuonglm
    Jun 13, 2014 at 17:22
  • Removing last / doesn't work. Example: /home/cuo/bin/ Expected: /home/cuo/bin
    – Marius
    Aug 11, 2017 at 8:34
  • How we get the time details with above command?
    – otong
    Oct 6, 2020 at 9:01
ls -td -- ./parent/*/ | head -n1 | cut -d'/' -f2

Difference to Herson's solution is the slash after *, which makes the shell ignore all non-dir files. Difference to Gnouc, it'll work if you are in another folder.

Cut needs to know the number of parent directories (2) in order to delete trailing '/'. If you don't have that, use

VAR=$(ls -dt -- parent/*/ | head -n1); echo "${VAR::-1}"

You can do:

ls -td -- ../parent/* | head -n 1

Obligatory zsh answer:


The characters in parentheses are glob qualifiers: / to match only directories, om to sort matches by increasing age, and [1] to retain only the first (i.e. newest) match. Add N if you want to get an empty array (normally you get a 1-elementy array) if there is no subdirectory of parent.

Alternatively, assuming that parent doesn't contain any shell globbing character:

latest_directory='parent/*(/om[1])'; latest_directory=$~latest_directory

If you don't have zsh but you have recent GNU tools (i.e. non-embedded Linux or Cygwin), you can use find, but it's cumbersome. Here's one way:

latest_directory_inode=$(find parent -mindepth 1 -maxdepth 1 -type d -printf '%Ts %i\n' | sort -n | sed -n '1 s/.* //p')
latest_directory=$(find parent -maxdepth 1 -inum "$latest_directory_inode")

There's a simple solution with ls, which works as long as no directory name contains newlines or (on some systems) non-printable characters:

latest_directory=$(ls -td parent/*/ | head -n1)

Following command will do the job even in case of directory name containing space :

cp `find . -mindepth 1 -maxdepth 1 -type d  -exec stat --printf="%Y\t%n\n" {} \;  |sort -n -r |head -1 |cut -f2'`/* /target-directory/.

The updated explanation of the stuff in the backticks is:

  • . - the current directory (you may want to specify an absolute path here)
  • -mindepth/-maxdepth - restrict the find command only to the immediate children of the current directory
  • -type d - only directories
  • -exec stat .. - outputs the modified time and the name of the directory from find separated with a tab (and not a space)
  • sort -n -r |head -1 | cut -f2 - date orders the directory and outputs the entire name of the most recently modified (even if containing some space as cut default delimiter tab)

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.