How to sort a list of files by time, given only the filenames

command linefilenamessort

Given a list of file names, how can I sort it by file modification time?

The resulting output needs to look exactly like the input with the exception that the data has been sorted accordingly.

Here is a sample of the input.

/jobs/crm/import/done/20140227-1359-0009.txt
/jobs/bridge/open-workitem/done/20140227-1359-0009.txt
/jobs/bridge/opened-workitem/done/20140227-1359-0009.txt
/jobs/bridge/update-workitem/done/20140227-1401-0001.txt
/jobs/bridge/update-workitem/done/20140227-1403-0001.txt
/jobs/tfs/import/done/20140227-1401-0001.txt
/jobs/tfs/import/done/20140227-1403-0001.txt
/jobs/tfs/open-workitem/done/20140227-1359-0009.txt

Best Answer

Assuming your input is small, and the file names don't contain spaces or other weird characters, you can just use ls.

ls -dt $(cat files)

$(cat files) puts the contents of files on the command line, and splits them on whitespace to get a list of arguments. ls -t takes a list of files as its arguments, sorts them by mtime, and prints them. -d is needed so it lists directories using their name, rather than their contents.

If that's not sufficient, you can try the decorate/sort/undecorate pattern, e.g.

$ while IFS=$'\n' read file; do
    printf '%d %s\n' "$(stat -c +%Y "$file")" "$file"
  done <files | sort -k1nr | cut -f 2- -d ' ' >files.sorted

where IFS=$'\n' read file; do ... done <files sets file to each newline-delimited entry in files in turn, printf...stat... turns <filename> into <mtime> <filename>, sort -k1nr sorts lines based on the first field in reverse numeric order, then cut removes the <mtime>, leaving you with just <filename>s in sorted order.

Related Question