Zahlen, die von stdin mit bc empfangen wurden, können nicht summiert werden

8

Ich versuche, die durchschnittliche Entropie der in einem Ordner enthaltenen Dateien zu berechnen, indem ich:

{ 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 Eine ausführbare Datei, die die Shannon-Entropie einer Datei berechnet und die folgenden Ausgaben liefert:

$ entropy foo
foo: 5.13232

Der oben genannte Befehl ist fehlerhaft mit:

(standard_in) 1: syntax error

Die generierte Ausgabe scheint jedoch keine Probleme zu haben:

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

Und das funktioniert auch:

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

Was ist los mit dem genannten Befehl?

user2064000
quelle
Bist du bereit zu benutzen awk? Wäre wesentlich einfacher.
Bernhard
2
Sie vermissen nur eine nachfolgende Endzeile für den bcBefehl: Vergleichen printf '(5.13232+2.479+1.4311+0)/3' | bc -lmit echo '(5.13232+2.479+1.4311+0)/3' | bc -l. (Ihr tr -d '\n'Befehl entfernt die nachfolgende neue Zeile, die bcbenötigt wird).
gniourf_gniourf
3
Eine einfache Lösung besteht darin, { cat; echo; }zwischen dem trund dem bc: einzufügen tr -d '\n' | { cat; echo; } | bc -loder das tr -d '\n'Teil durch { tr -d '\n'; echo; }
Folgendes
3
Verwenden Sie paste -sd'\0' -statt tr -d '\n', um das letzte Zeilenumbruchzeichen beizubehalten. (Siehe auch paste -sd+ -, um Linien mit zu verbinden +).
Stéphane Chazelas

Antworten:

12

Und das funktioniert auch: echo '(2.1+2.1)/2' | bc -l

Ah, aber hast du versucht:

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

Mit echo -nwird das Gleiche erreicht - es gibt keine terminierende Newline, und das ist Ihr Problem.

Goldlöckchen
quelle
5

bchat eine ziemlich spezielle Syntax. dcist weniger wählerisch:

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

Ich denke , das macht das, was Sie versuchen, aber ich bin mir nicht ganz sicher. Ein Ausgabebeispiel, das größer als eine einzelne Zeile ist, würde helfen.

mikeserv
quelle
2
Sie könnten auch dcdie ganze Arbeit erledigen : { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. Das Hässliche 10k[+]sa[z2!>az2!>b]sbzsclbxlc/pist ein Haufen Müll, der dcden Durchschnitt der auf dem Stapel verbleibenden Zahlen berechnet (mit einer Skala von 10) :D.
gniourf_gniourf
@gniourf_gniourf - das ist besser als ich, Mann. Machen Sie eine Antwort und ich werde meine löschen.
Mikeserv
Nein, deine ist großartig! Ich kann diesen dcMüll sowieso nicht wirklich befürworten - es ist nur gut, in diesem Kommentarbereich zu bleiben.
gniourf_gniourf
1
@gniourf_gniourf - es ist allerdings ziemlich schnell verrückt. Ich möchte lernen, wie man es besser benutzt. Danke für das
Lernmaterial