Невозможно суммировать числа, полученные от стандартного ввода, используя bc

8

Я пытаюсь вычислить среднюю энтропию файлов, содержащихся в папке, используя:

{ 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 являясь исполняемым файлом, который вычисляет энтропию Шеннона файла и дает выходные данные в виде:

$ entropy foo
foo: 5.13232

Вышеупомянутые ошибки команды с:

(standard_in) 1: syntax error

Однако сгенерированный вывод, похоже, не имеет проблем:

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

И это тоже работает:

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

Что не так с упомянутой командой?

user2064000
источник
Вы готовы использовать awk? Было бы существенно проще.
Бернхард
2
Вам просто не хватает конечного конца bcкоманды: сравните printf '(5.13232+2.479+1.4311+0)/3' | bc -lс echo '(5.13232+2.479+1.4311+0)/3' | bc -l. (ваша tr -d '\n'команда удаляет завершающий символ новой строки bc).
gniourf_gniourf
3
Простое решение - вставить { cat; echo; }между и trи bc: tr -d '\n' | { cat; echo; } | bc -lили заменить tr -d '\n'деталь на:{ tr -d '\n'; echo; }
gniourf_gniourf
3
Используйте paste -sd'\0' -вместо того, tr -d '\n'чтобы сохранить последний символ новой строки. (см. также, paste -sd+ -чтобы соединить линии с +).
Стефан Шазелас

Ответы:

12

И это тоже работает: echo '(2.1+2.1)/2' | bc -l

Ах, но вы пробовали:

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

Использование echo -nприведет к тому же - нет завершающего символа новой строки, и это ваша проблема.

лютик золотистый
источник
5

bcимеет довольно специфический синтаксис. dcменее разборчив:

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

Я думаю, что это то, что вы пытаетесь сделать, но я не совсем уверен. Выходная выборка, больше чем одна строка, поможет.

mikeserv
источник
2
Вы могли бы использовать , dcчтобы сделать все работы тоже: { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. Уродливая 10k[+]sa[z2!>az2!>b]sbzsclbxlc/pкуча мусора, которая говорит, dcчтобы вычислить среднее число чисел, оставшихся в стеке (со шкалой 10) :D.
gniourf_gniourf
@gniourf_gniourf - это лучше меня, чувак. Сделай ответ, а я удалю свой.
mikeserv
Нет, у тебя все отлично! В dcлюбом случае, я не могу защищать этот мусор - хорошо, что меня оставляют в этой области комментариев.
gniourf_gniourf
1
@gniourf_gniourf - это довольно быстро. Я хочу научиться использовать его лучше. Спасибо за учебный материал ...
mikeserv