Tidak dapat menjumlahkan angka yang diterima dari stdin menggunakan bc

8

Saya mencoba menghitung rata-rata entropi file yang terkandung dalam folder menggunakan:

{ 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 menjadi executable yang menghitung entropi Shannon file, memberikan output dari bentuk:

$ entropy foo
foo: 5.13232

Perintah yang disebutkan di atas salah dengan:

(standard_in) 1: syntax error

Namun, output yang dihasilkan tampaknya tidak memiliki masalah:

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

Dan ini juga bekerja:

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

Apa yang salah dengan perintah yang disebutkan?

pengguna2064000
sumber
Apakah Anda bersedia menggunakannya awk? Akan jauh lebih mudah.
Bernhard
2
Anda hanya melewatkan garis belakang akhir untuk bcperintah: bandingkan printf '(5.13232+2.479+1.4311+0)/3' | bc -ldengan echo '(5.13232+2.479+1.4311+0)/3' | bc -l. ( tr -d '\n'perintah Anda menghapus baris tambahan yang bcdibutuhkan).
gniourf_gniourf
3
Cara mudah adalah menyisipkan { cat; echo; }antara trdan bc: tr -d '\n' | { cat; echo; } | bc -latau mengganti tr -d '\n'bagian dengan:{ tr -d '\n'; echo; }
gniourf_gniourf
3
Gunakan paste -sd'\0' -alih-alih tr -d '\n'untuk mempertahankan karakter baris baru terakhir. (lihat juga paste -sd+ -untuk bergabung dengan garis +).
Stéphane Chazelas

Jawaban:

12

Dan ini juga bekerja: echo '(2.1+2.1)/2' | bc -l

Ah, tetapi apakah Anda mencoba:

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

Menggunakan echo -nakan mencapai hal yang sama - tidak ada penghentian baris baru, dan itu masalah Anda.

goldilocks
sumber
5

bcmemiliki beberapa sintaks yang cukup khusus. dckurang pemilih:

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

Saya pikir itu melakukan apa yang Anda coba lakukan, tetapi saya tidak sepenuhnya yakin. Sampel keluaran yang lebih besar dari satu baris akan membantu.

mikeserv
sumber
2
Anda bisa menggunakan dcuntuk melakukan semua pekerjaan terlalu: { find . -type f -exec entropy \{\} | sed 's/.*://' ; echo ' 10k[+]sa[z2!>az2!>b]sbzsclbxlc/p'; } | dc. Yang jelek 10k[+]sa[z2!>az2!>b]sbzsclbxlc/padalah sekelompok sampah yang memberitahu dcuntuk menghitung rata-rata angka yang tersisa di tumpukan (dengan skala 10) :D.
gniourf_gniourf
@ gniourf_gniourf - itu lebih baik dari saya, kawan. Buat jawaban dan saya akan menghapus milik saya.
mikeserv
Tidak, milikmu hebat! Saya benar-benar tidak bisa menganjurkan dcsampah ini — hanya baik dibiarkan di area komentar ini.
gniourf_gniourf
1
@ gniourf_gniourf - cukup gila, cepat. Saya ingin belajar bagaimana menggunakannya dengan lebih baik. Terima kasih untuk bahan pelajarannya ...
mikeserv