This is a surprisingly tough problem. Bash is simply not very good at working with (slightly) complex data structures like arrays.
I think the only conceivable robust solution will require a loop. This is the easiest way I can think of:
function firstfunction {
local -A map=(['-f']='--format');
local -a args=();
local arg;
for arg in "$@"; do
if [[ -v map[$arg] ]]; then
args+=("${map[$arg]}");
else
args+=("$arg");
fi;
done;
echo ${args[@]+"${args[@]}"}; ## replace echo with secondfunction to run
};
firstfunction;
##
firstfunction a b;
## a b
firstfunction x -f -fff -f-f -fxy x-f \ -f -f\ -f;
## x --format -fff -f-f -fxy x-f -f -f --format
Using ${args[@]+"${args[@]}"}
instead of just "${args[@]}"
for the final expansion works around the ill-advised design decision the bash developers made to reject an empty array as an "unbound variable" if you have the nounset
set option (set -u
) enabled. See Bash empty array expansion with `set -u`.
Alternative:
function firstfunction {
local -A map=(['-f']='--format');
local -a args=("$@");
local -i i;
for ((i = 0; i < ${#args[@]}; ++i)); do
if [[ -v map[${args[i]}] ]]; then
args[i]="${map[${args[i]}]}";
fi;
done;
echo ${args[@]+"${args[@]}"}; ## replace echo with secondfunction to run
};