Seu código diz para imprimir uma string. Não diz em lugar nenhum que essa string é, de fato, uma expressão aritmética que você deseja avaliar. Então você não pode razoavelmente esperar que sua expressão seja avaliada.
Seu código está abaixo do ideal. $(wc -l)
contará o número de correspondências retornadas por grep
, mas há uma maneira mais simples: execute grep -c
. $(ls | wc -l)
é uma maneira não confiável de contar os arquivos não pontuais no diretório atual, porque a saída de ls
não é confiável ; $(set -- *; echo $#)
é uma maneira confiável de fazer isso (supondo que haja pelo menos um arquivo correspondente; se essa suposição não for válida, use $(set -- *; if [ -e "$1" ]; then echo $#; else echo 0; fi
, mas observe que isso resultará em uma divisão por zero abaixo da qual você deve tratar como um condição de erro de uma forma ou outra). Então você pode escrever seu código desta maneira:
matches=$(grep -c "bla bla blah" blah*)
files=$(set -- *; echo $#)
echo "Blah: $matches / $files * 100"
ou você pode alinhar o cálculo dos dois valores intermediários:
echo "Blah: $(grep -c "bla bla blah" blah*) / $(set -- *; echo $#) * 100"
Agora, para realizar a aritmética, você pode usar a expansão aritmética integrada do shell , mas é limitado a operações inteiras, portanto, o operador /
será arredondado para o número inteiro mais próximo.
echo "Blah: $(($matches * 100 / $files))"
Em ksh93, zsh e yash, mas não em outros shells, você obtém aritmética de ponto flutuante se houver algo na expressão para forçar um ponto flutuante, como uma constante de ponto flutuante. Este recurso não está presente no shell Bourne, ksh88, pdksh, bash, ash.
echo "Blah: $(($matches * 100.0 / $files))"
O utilitário bc
executa operações no número decimal com precisão arbitrária.
echo "Blah: $(echo "scale=2; $matches * 100 / $files" | bc)"
Outro utilitário padrão que pode executar computação de ponto flutuante (com menos funções matemáticas disponíveis) é awk
.
echo "$matches" "$files" | awk '{print "Blah:", $1 * 100 / $2}'