我有一个源文件,其中包含用Bash编写的代码。源文件中定义了一些函数,如
- abc(i,j,k)
我需要使用shell脚本读取源文件,并且需要生成所有可能的函数调用组合,如:
- abc(i,j,k)
- abc(i,j,)
- abc(i,,j)
- abc(,j,k)
- abc(,,k)
- abc(i,,)
- abc(,j,)
- abc(,,)
对于三个参数,有8种组合,因此组合将根据参数的数量增加或减少。
答案 0 :(得分:4)
bash的大括号扩展可以生成组合:
printf -- "- abc(%s}\n" {i,},{j,},{k,}
但我认为你想要它比那更有活力。这是丑陋的代码,但它的工作原理。
while IFS= read -r line; do
# match a line that looks like a function,
# and capture the function name and the parameter list
if [[ $line =~ " - "([[:alnum:]]+)\(([a-z,]+)\) ]]; then
funcname=${BASH_REMATCH[1]}
# split the comma-separated parameters into an array
IFS=, read -ra params <<< "${BASH_REMATCH[2]}"
# create the brace-expansion string
printf -v combos "{%s,}," "${params[@]}"
# and this is the command to print out the combinations
cmd=( printf -- "\"- $funcname(%s)\n\"" ${combos%,} )
# now evaluate it
eval "${cmd[@]}"
fi
done <<END
- abc(i,j,k)
END
- abc(i,j,k)
- abc(i,j,)
- abc(i,,k)
- abc(i,,)
- abc(,j,k)
- abc(,j,)
- abc(,,k)
- abc(,,)
答案 1 :(得分:2)
也许有一个较短的版本。我添加纯bash溶剂:
#!/bin/bash
# extract arguments to $arg
fnc=" - abc(i,j,k)"
pre=${fnc%%(*}
post=${fnc##*)}
arg=${fnc#*(}
arg=${arg%)*}
# put arguments to arr array
IFS=, read -a arr <<<"$arg"
num=${#arr[@]}
# Generate all output lines
for((i=0; i<1<<num; ++i));{
tmp=()
for ((j=0; j<num; ++j));{
if ((i & (1<<j))); then tmp[j]=""
else tmp[j]=${arr[j]}
fi
}
printf -v tmp ,%s "${tmp[@]}"
echo "$pre("${tmp:1}")$post"
}
输出:
- abc(i,j,k)
- abc(,j,k)
- abc(i,,k)
- abc(,,k)
- abc(i,j,)
- abc(,j,)
- abc(i,,)
- abc(,,)
该脚本使用变量fnc
作为输入。它分为三部分:pre,args,post。 arg
是数组化的。然后它为每个可能的变化产生输出。