Não é possível somar números recebidos do stdin usando bc

8

Estou tentando calcular a entropia média dos arquivos contidos em uma pasta usando:

{ echo '('; find . -type f -exec entropy {} \; | \
  grep -Eo '[0-9.]+$' | \
  sed -r 's/$/+/g'; echo '0)/'; 
  find . -type f | wc -l; }  | \
tr -d '\n' | bc -l

entropy sendo um executável que calcula a entropia de Shannon de um arquivo, fornecendo saídas do formulário:

$ entropy foo
foo: 5.13232

O comando acima mencionado erros com:

(standard_in) 1: syntax error

No entanto, a saída gerada parece não ter problemas:

$ { echo '('; find . -type f -exec entropy {} \; | \
    grep -Eo '[0-9.]+$' | \
    sed -r 's/$/+/g'; echo '0)/'; \
    find . -type f | wc -l; }  | \
  tr -d '\n'
(5.13232+2.479+1.4311+0)/3

E isso também funciona:

$ echo '(2.1+2.1)/2' | bc -l
2.1

O que há de errado com o comando mencionado?

user2064000
fonte
Você está disposto a usar awk? Seria substancialmente mais fácil.
Bernhard
2
Você está perdendo uma linha final final para o bccomando: compare printf '(5.13232+2.479+1.4311+0)/3' | bc -lcom echo '(5.13232+2.479+1.4311+0)/3' | bc -l. (seu tr -d '\n'comando remove a nova linha à direita que bcprecisa).
gniourf_gniourf
3
Uma solução fácil é inserir { cat; echo; }entre o tre o bc: tr -d '\n' | { cat; echo; } | bc -lou substituir a tr -d '\n'peça por:{ tr -d '\n'; echo; }
gniourf_gniourf 23/06
3
Use em paste -sd'\0' -vez de tr -d '\n'para preservar o último caractere de nova linha. (veja também paste -sd+ -para unir linhas +).
Stéphane Chazelas

Respostas:

12

E isso também funciona: echo '(2.1+2.1)/2' | bc -l

Ah, mas você tentou:

echo '(2.1+2.1)/2' | tr -d '\n' | bc -l
(standard_in) 1: syntax error

O uso echo -nfará a mesma coisa - não há nova linha final, e esse é o seu problema.

Cachinhos Dourados
fonte
5

bctem uma sintaxe bem particular. dcé menos exigente:

find . -type f -exec entropy \{\} + |
sed 's/.*://;N;N;s/\n[^:]*:/+/g;s/+//;s|$| 3/p|' |
dc

Eu acho que faz o que você está tentando fazer, mas não tenho certeza. Uma amostra de saída maior que uma única linha ajudaria.

mikeserv
fonte
2
Você poderia usar dcpara fazer todo o trabalho também: { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. O feio 10k[+]sa[z2!>az2!>b]sbzsclbxlc/pé um monte de lixo que indica dcpara calcular a média dos números restantes na pilha (com uma escala de 10) :D.
gniourf_gniourf
@gniourf_gniourf - isso é melhor do que eu, cara. Faça uma resposta e eu vou excluir a minha.
mikeserv
Não, o seu é ótimo! Eu realmente não posso defender esse dclixo de qualquer maneira - só é bom ficar nessa área de comentários.
gniourf_gniourf
1
@gniourf_gniourf - é muito louco rápido, no entanto. Eu quero aprender a usá-lo melhor. Obrigado pelo material de estudo ...
mikeserv