Bash – Sort files with a specific extension by modified time and store them into an array

bashfilesshell-scriptsorttimestamps

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

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]} 

Best Answer

In zsh it's as easy as

array=(*.sh(Nom))

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]}"

Related Question