我想创建 256 个做同样事情的函数
基本上,我想要一个能够不区分大小写地调用的函数。
示例:我希望applepie()
能够以不区分大小写的方式调用:
applepie(){
for B in "$@";
do
another_function_in_my_bash_profile $B
blah blah
# more stuff ...
done
}
最直接的方法是声明另外 255 个函数,并用一些大写字母表示:
Applepie(){
for B in "$@";
do
another_function_in_my_bash_profile $B
blah blah
# more stuff ...
done
}
和
aPplepie(){
for B in "$@";
do
another_function_in_my_bash_profile $B
blah blah
# more stuff ...
done
}
。
一直到
APPLEPIE(){
for B in "$@";
do
another_function_in_my_bash_profile $B
blah blah
# more stuff ...
done
}
总共有 256 个(2 的 8 次方)
有可能快速完成吗?或者是否有一种更"内置"的方法,例如
case-insensitive appelepie(){
for B in "$@";
do
another_function_in_my_bash_profile $B
blah blah
# more stuff ...
done
}
或者有可能像这样做
case-insensitive APPLEPIE(){
command -pass_all_parameters applepie
}
可以将所有参数传递给Applepie,而不是使用for循环for B in "$@";
?
定义全小写函数名称并使用bash
的陷阱来伪造不区分大小写的函数名称(需要bash
4,您需要在OS X上自行安装):
command_not_found_handle () {
cmd_name=${1,,}
shift
$cmd_name "$@"
}
因此,如果apple
是一个函数,但您尝试将其调用为 ApPlE
,则command_not_found_handle
以命令作为参数进行调用。第一行采用第一个参数(ApPlE
)并小写。然后,它尝试使用原始参数运行apple
。
这是一个非常迟钝的答案,绝对不是单行的,但这是如何在 bash 中完成的,在 bc
和 tr
的帮助下(适用于 osx):
funcname="applepie"
strlen=${#funcname}
numcombos=$((2 ** strlen))
for ((i=1; i<numcombos; i++)); do
binstr=$(echo "obase=2; $i" | bc )
zlen=$((1+strlen-${#binstr}))
binstr=$(printf "%0${zlen}x" 0)${binstr}
binstr=${binstr:1:$strlen}
casename=""
for ((j=0; j<strlen; j++)); do
if [ ${binstr:$j:1} = 1 ]; then
casename=${casename}$(tr '[a-z]' '[A-Z]' <<< ${funcname:$j:1})
else
casename=${casename}${funcname:$j:1}
fi
done
alias ${casename}=${funcname}
done
这将执行以下操作;
- 获取函数名称的长度
- 计算出案例组合的数量 (2^n)
- 循环遍历每个组合
- 将组合数字转换为二进制数字字符串
- 摆弄二进制数字字符串,使其与函数名称的长度相同
- 通过函数名称的每个字符和二进制数字字符串进行索引,并且仅在相应的二进制数字为 1 时才更改 toupper() 大小写
- 将字符重新组合为字符串
- 从每个组合到函数名称的 bash 别名
假定函数已定义,并且具有全小写名称。
这是使用纯 bash 和递归函数的另一种方法。 当我看到递归函数时,我通常会跑一英里,但在这种情况下,它工作得很好:
funcname="applepie"
function cr {
if [ "$1" ]; then
cr "${1:1:${#1}}" "${2:1:${#2}}" "${3}${1:0:1}"
cr "${1:1:${#1}}" "${2:1:${#2}}" "${3}${2:0:1}"
else
alias $3=$funcname
fi
}
cr $funcname $(tr '[a-z]' '[A-Z]' <<< $funcname) ""