É uma coisa bastante estranha de se fazer, geração dinâmica de declarações de caso ... mas sim, é possível.
Eu faria algo como o seguinte (se eu tivesse explorado todas outras abordagens em que eu poderia pensar; não sei se eu recomendaria isso):
. <( awk -F= 'BEGIN { print "case \"$line\" in" }
{ print $1 ") ret=" $2 ";;" }
END { print "esac" }' patternfile )
Se patternfile
contiver
pattern1=result1
pattern2=result2
pattern3=result3
o comando awk
por si só produziria
case "$line" in
pattern1) ret=result1;;
pattern2) ret=result2;;
pattern3) ret=result3;;
esac
e com a construção . <( awk ... )
, isso será originado em seu script, como se você tivesse escrito a opção case diretamente em seu arquivo de script.
Isso responde "criação dinâmica de instrução de caso" em um script de shell. No entanto, como você planeja fazer isso dentro de um loop , o acima seria uma maneira muito ruim de fazer isso, já que você executaria awk
10.000 vezes no seu patternfile
, superando assim qualquer benefício de desempenho possível.
Em vez disso, seria melhor escrever o gerador de código para criar um switch de caso dentro de uma definição de função —criar e fornecer uma definição de função inteira, em outras palavras:
# At the top of your script file:
. <( awk -F= 'BEGIN { print "my_case_switch_function() {"
print "case \"$1\" in" }
{ print $1 ") ret=" $2 ";;" }
END { print "esac"
print "}" }' patternfile )
# Within your while loop (or wherever else you want):
my_case_switch_function "$line"
Isso permitiria que você reutilizasse a opção case
% e mais (10.000 vezes, se preferir) depois de processar apenas patternfile
uma vez. Assim, o desempenho é tão bom quanto você obteria se você criasse manualmente o switch de caso do patternfile
e codificasse-o em seu script (exceto pela pequena sobrecarga de execução de awk
em um arquivo de 150 linhas, que é insignificante próximo ao processamento de 10.000 linhas).
No entanto, deve ser reiterado: as opções de caso de script de shell são não a ferramenta para processar um arquivo de 10.000 linhas linha por linha. Portanto, mesmo que essa solução se aproxime do desempenho que você poderia obter com um switch de caso codificado, provavelmente ainda será lento.
Para citar Stephane Chazelas :
As said earlier, running one command has a cost. A huge cost if that command is not builtin, but even if they are builtin, the cost is big.
And shells have not been designed to run like that, they have no pretension to being performant programming languages. They are not, they're just command line interpreters. So, little optimisation has been done on this front.