Impossible de additionner les nombres reçus de stdin à l'aide de bc

8

J'essaie de calculer l'entropie moyenne des fichiers contenus dans un dossier en utilisant:

{ 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 étant un exécutable qui calcule l'entropie Shannon d'un fichier, donnant des sorties de la forme:

$ entropy foo
foo: 5.13232

La commande susmentionnée génère des erreurs avec:

(standard_in) 1: syntax error

Cependant, la sortie générée semble n'avoir aucun problème:

$ { 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

Et cela fonctionne aussi:

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

Quel est le problème avec la commande mentionnée?

user2064000
la source
Êtes-vous prêt à utiliser awk? Ce serait beaucoup plus facile.
Bernhard
2
Il vous manque juste une fin de ligne pour la bccommande: comparer printf '(5.13232+2.479+1.4311+0)/3' | bc -lavec echo '(5.13232+2.479+1.4311+0)/3' | bc -l. (votre tr -d '\n'commande supprime la nouvelle ligne de fin qui a bcbesoin).
gniourf_gniourf
3
Une solution simple consiste à insérer { cat; echo; }entre le tret le bc: tr -d '\n' | { cat; echo; } | bc -lou de remplacer la tr -d '\n'pièce par:{ tr -d '\n'; echo; }
gniourf_gniourf
3
Utilisez paste -sd'\0' -au lieu de tr -d '\n'pour conserver le dernier caractère de nouvelle ligne. (voir aussi paste -sd+ -pour joindre des lignes avec +).
Stéphane Chazelas

Réponses:

12

Et cela fonctionne aussi: echo '(2.1+2.1)/2' | bc -l

Ah, mais avez-vous essayé:

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

L'utilisation echo -naccomplira la même chose - il n'y a pas de fin de ligne, et c'est votre problème.

boucle d'or
la source
5

bca une syntaxe assez particulière. dcest moins exigeant:

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

Je pense que cela fait ce que vous essayez de faire, mais je ne suis pas totalement certain. Un échantillon de sortie plus grand qu'une seule ligne serait utile.

mikeserv
la source
2
Vous pouvez utiliser dcpour faire tout le travail aussi: { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. Le laid 10k[+]sa[z2!>az2!>b]sbzsclbxlc/pest un tas d'ordure qui indique dcde calculer la moyenne des nombres restants sur la pile (avec une échelle de 10) :D.
gniourf_gniourf
@gniourf_gniourf - c'est mieux que moi, mec. Faites-en une réponse et je supprimerai la mienne.
mikeserv
Non, le tien est super! Je ne peux pas vraiment défendre cette dcordure de toute façon - c'est seulement bon d'être laissé dans cette zone de commentaire.
gniourf_gniourf
1
@gniourf_gniourf - c'est assez rapide, cependant. Je veux apprendre à mieux l'utiliser. Merci pour le matériel d'étude ...
mikeserv