Sort and source configuration files from one of two directories In a zsh I want to loop over all files in a configuration files' directory (/etc/myapp/) to source them. The files should be sourced in order and are named with two leading digits 10-early 40-middle 99-last. A user without write permission to /etc should be allowed to extend the list of files and override the global ones. This is done by creating a $HOME/.myapp directory. The user files should be sourced in order with the global files, i.e. /etc/myapp/10-early $HOME/.myapp/20-rightafter /etc/myapp/40-middle $HOME/.myapp/90-late /etc/myapp/99-last. A user should also be allowed to override global files, i.e. when $HOME/.myapp/99-last exists, then /etc/myapp/99-last should be skipped.

As answerded here and here, I create an array with all the config files and then use basename on the array (like here) to restrict it to the NN-lllll part and sort them. Eventually each file gets sourced from $HOME/.myapp if it exists there, and from /etc/myapp otherwise.

# https://stackoverflow.com/a/10981499
# https://unix.stackexchange.com/a/26825
thefiles=(/etc/myapp/* $HOME/.myapp/*(N))
# https://stackoverflow.com/a/9516801
uniquified=( $( for f in "${thefiles[@]}" ; do basename $f ; done | sort -V | uniq) )
for f in $uniquified
do
# -r checks if file exists and is readable
  if [[ -r $HOME/.myapp/$f ]]
  then
    source $HOME/.myapp/$f
  else
    source /etc/myapp/$f
  fi
done


Is there a more elegant solution and should I be aware of errors I need to catch?
You can combine sort -V | uniq into sort -uV.

Note that the -V flag of sort doesn't exist in BSD.
Consider replacing it with -n if that's good enough.

The if inside the loop can be written more compactly as:

[[ -r $HOME/.myapp/$f ]] &amp;&amp; source $HOME/.myapp/$f || source /etc/myapp/$f


You could also replace source with . which is equivalent.