I have found many answers to sort the files of directory and even to save them in an array.

Sorting Example

ls -t 

Directory listing in array


My particular problem needs to sort files with a specific extension (say *.sh) based on their modification date/time, and save all these sorted files in array to be used later for editing or deleting file.

For example, after I have the sorted files in the array I could execute remove the most recent file by the following command.

rm ${array[0]} 
  • @Osaid- array=($(ls -t *.sh)) is quick and dirty though it will not handle file names with spaces in them.
    – fd0
    Commented Jul 6, 2015 at 13:22

2 Answers 2


In zsh it's as easy as


The glob qualifier om causes the matches to be sorted by modification time (newest first), and N forces the array to be empty if there is no match (instead of causing an error).

In other shells such as bash, there's no good way of sorting by time. You can use ls -t, but that can break because the output is ambiguous. If you know that your file names only contain characters that ls considers to be printable, and that are not whitespace or \[*?, then you can use a command substitution:

array=($(ls -t -- *.sh 2>/dev/null))

You can make this more robust by protecting wildcard characters and horizontal whitespace, but newlines and nonprintable characters remain a problem.

IFS=$'\n'; set -f
array=($(ls -t -- *.sh 2>/dev/null))
unset IFS; set +f

Except in zsh, don't forget the double quotes when refering to the value of a variable, as well as -- to protect files whose name begins with a dash and would otherwise be interpreted as options, e.g. rm -- "${array[0]}"

  • How to sort a zsh array by modification date?
    – HappyFace
    Commented Apr 7, 2020 at 16:40
  • @HappyFace Modification date of the array entry? Zsh doesn't keep track of that. Modification date of files, assuming that the array entries are file names? I don't think there's a particularly easy way. You can make an array that contains timestamps followed by file names, sort it and strip the timestamp prefix. Commented Apr 7, 2020 at 16:50

To do this with ls robustly you should not split on anything but the path delimiter - that's what it's for.

IFS=/; set -f
set -- $(ls -dt ./*)

That will sort all non-dot files in the current directory and place the results in the shell array $@. Given a POSIX ls, this is not susceptible to any kind of filename mangling whatsoever: special characters of all kinds - including newlines - persist in the delimited results. Each one (but the last), though, will have an extra . dot appended to the name. If you wanted to put the results in a more permanent array, you could handle the jobs together, like:

until [ -z "$2" ] &&
      a+="$1" && shift
do    a+="${1%?}"

No matter what kind of nonsense blogs some others might link you to, you can handle ls's results robustly if you just know what to look for.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .