Search code examples
sortingshposixquicksort

(Quick-) sorting a list of files in POSIX sh


Quite often, I find myself thinking that it would be good to have a general solution that is as portable as possible, "if I ever need this on a weird or constraint machine".

I have been searching for a way to more or less efficiently sort a list of files in a directory in reverse order, using POSIX sh and tools only.

This should work with arbitrarily named files, including such with control code characters (e.g., newlines) in their name.


Solution

  • So the idea is to process a set of files in lexicographical reverse order. As you know, you cannot parse ls, due to the weird filenames. Since this is POSIX, we don't have arrays. So here is a solution that might work.

    Glob expressions return a list of possible filenames in lexicographical order. So you could do something like

    for file in /path/to/dir/*; do
        [ -e "${file}" ] || continue
        some_command "${file}"
    done
    

    If you want to reverse it, you can just do:

    set -- /path/to/dir/*
    i=$#
    while [ "$i" -gt 0 ]; do 
        eval "file=\${${i}}"; i=$((i-1));
        [ -e "${file}" ] || continue
        some_command "$file"
    done
    

    Note: we have to use an evil eval for the evaluation of the positional variable.

    Update: it is possible that positional variables are already in use. In this case you can do the following:

    j=$#
    set -- /path/to/dir/* "$@"
    i=$(($#-$j))
    while [ "$i" -gt 0 ]; do 
        eval "file=\${${i}}"; i=$((i-1));
        [ -e "${file}" ] || continue
        some_command "$file"
    done
    shift "$i"