Impossibile sommare i numeri ricevuti da stdin utilizzando bc


8

Sto cercando di calcolare l'entropia media dei file contenuti in una cartella 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 essendo un eseguibile che calcola l'entropia di Shannon di un file, fornendo output del modulo:

$ entropy foo
foo: 5.13232

Il comando sopra citato si risolve con:

(standard_in) 1: syntax error

Tuttavia, l'output generato sembra non avere problemi:

$ { 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 funziona anche questo:

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

Cosa c'è di sbagliato nel comando citato?


Sei disposto a usare awk? Sarebbe sostanzialmente più semplice.
Bernhard,

2
Manca solo una linea finale finale per il bccomando: confronta printf '(5.13232+2.479+1.4311+0)/3' | bc -lcon echo '(5.13232+2.479+1.4311+0)/3' | bc -l. (il tuo tr -d '\n'comando rimuove la nuova riga finale bcnecessaria).
gniourf_gniourf,

3
Una soluzione semplice è inserire { cat; echo; }tra il tre il bc: tr -d '\n' | { cat; echo; } | bc -lo sostituire la tr -d '\n'parte con:{ tr -d '\n'; echo; }
gniourf_gniourf

3
Utilizzare paste -sd'\0' -invece di tr -d '\n'per conservare l'ultimo carattere di nuova riga. (vedi anche paste -sd+ -per unire le linee con +).
Stéphane Chazelas,

Risposte:


12

E funziona anche questo: echo '(2.1+2.1)/2' | bc -l

Ah, ma hai provato:

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

L'uso echo -nconsentirà di ottenere lo stesso risultato: non esiste una nuova riga che termina e questo è il tuo problema.


5

bcha una sintassi abbastanza particolare. dcè meno esigente:

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

Io penso che fa quello che si sta cercando di fare, ma non sono del tutto certo. Un campione di output più grande di una singola riga sarebbe di aiuto.


2
Si potrebbe utilizzare dcper fare tutto il lavoro troppo: { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. Il brutto 10k[+]sa[z2!>az2!>b]sbzsclbxlc/pè un mucchio di spazzatura che dice dcdi calcolare la media dei numeri lasciati in pila (con una scala di 10) :D.
gniourf_gniourf,

@gniourf_gniourf - è meglio di me, amico. Dagli una risposta e cancellerò la mia.
Mikeserv,

No, il tuo è fantastico! Non posso davvero sostenere questa dcspazzatura in ogni caso, è solo bello essere lasciati in quest'area di commento.
gniourf_gniourf,

1
@gniourf_gniourf - è abbastanza veloce, però. Voglio imparare a usarlo meglio. Grazie per il materiale di studio ...
mikeserv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.