I have a bash script (seen here) that I'm using to sort a list of files in subdirectories by filename.
This script appends sorted files in hooks/pre-relevant/
, then files named hooks/pre-relevant
, then files named hooks/relevant
, then sorted files in hooks/relevant/
, using the append_hook
function below:
hooks=()
# Run a hook script, if it's executable, with the input from this invocation
append_hook () {
if [[ -f "$1" && -x "$1" ]]; then
hooks+=("$1")
fi
}
I'm testing it with this directory structure:
testing-range/plugins/
|-- bar
| `-- hooks
| |-- irrelevant
| |-- only-one
| `-- relevant
|-- dickory
| `-- hooks
| `-- pre-relevant
|-- doc
| `-- hooks
| |-- perl-envsubst
| `-- relevant
| |-- 00
| `-- 20
|
|-- factory
| `-- hooks
| `-- relevant
`-- hickory
`-- hooks
|-- pre-relevant
| `-- 30
`-- relevant
`-- 10
When I use this multi-step array code to append the files:
append_numbered_hooks () {
# Gather every file into an array, prefixing each item with the
# filename of the script (its position in sort order)
local filelist=()
for hook in "$PLUSHU_ROOT"/plugins/*/hooks/"$hookname"/*; do
filelist+=("${hook##*/}/$hook")
done
# Sort the array numerically
printf '%s\0' "${filelist[@]}" | sort -nz | IFS= read -rd '' -a filelist
# Append each script in sorted order
for hookline in "${filelist[@]}"; do
append_hook "${hookline#*/}"
done
}
I get almost the correct output:
hickory/hooks/pre-relevant/30
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
doc/hooks/relevant/00
doc/hooks/relevant/20
hickory/hooks/relevant/10
Yet, when I append the files using this simpler pipeline:
append_numbered_hooks () {
for hook in "$PLUSHU_ROOT"/plugins/*/hooks/"$1"/*; do
printf '%s\0' "${hook##*/}/$hook"
done | sort -nz | while IFS= read -rd '' hookline; do
append_hook "${hookline#*/}"
done
}
The numbered files don't show up in a for "${hooks[@]}" loop:
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
What's going on? The correct values should be:
hickory/hooks/pre-relevant/30
dickory/hooks/pre-relevant
bar/hooks/relevant
factory/hooks/relevant
doc/hooks/relevant/00
hickory/hooks/relevant/10
doc/hooks/relevant/20
set -- "$PLUSHU_ROOT"/*/hook[s]/*relevant/[0-9]*[0-9]; while [ -n "$1" ]; do [ -z "${1##*/hook\[*}" ] || env - "$1" ; shift; done
should be pretty close to what you need, though maybe you have to sort it first. But that's easily done, because all of the returns are in your shell"$@"
array.