Saya berusaha keras untuk membandingkan dua angka floating point dalam skrip bash. Saya harus variabel, misalnya
let num1=3.17648e-22
let num2=1.5
Sekarang, saya hanya ingin melakukan perbandingan sederhana dari dua angka ini:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
Sayangnya, saya memiliki beberapa masalah dengan perawatan yang tepat dari num1 yang dapat berupa "e-format". :(
Bantuan, petunjuk dipersilahkan!
Jawaban:
Lebih nyaman
Ini dapat dilakukan dengan lebih nyaman menggunakan konteks numerik Bash:
Penjelasan
Memiprat melalui perintah kalkulator dasar
bc
mengembalikan 1 atau 0.Opsi
-l
ini setara dengan--mathlib
; itu memuat perpustakaan matematika standar.Menutup seluruh ekspresi antara tanda kurung ganda
(( ))
akan menerjemahkan nilai-nilai ini menjadi benar atau salah.Tolong, pastikan bahwa
bc
paket kalkulator dasar diinstal.Ini sama-sama berfungsi untuk mengapung dalam format ilmiah, asalkan menggunakan huruf kapital
E
, misalnyanum1=3.44E6
sumber
bc
menginstal paket kalkulator.0: not found
pernyataan ituif (( $(echo "$TOP_PROCESS_PERCENTAGE > $THRESHOLD" | bc -l) )); then
.bc
dalam backticks atau$()
kemudian ke(( ))
... yaitu(( $(bc -l<<<"$a>$b") ))
dan tidak(( bc -l<<<"$a>$b" ))
.E
, dan semua kesalahan sintaks akan hilang.bash hanya menangani bilangan bulat matematika tetapi Anda dapat menggunakan
bc
perintah sebagai berikut:Perhatikan bahwa tanda eksponen harus huruf besar
sumber
bc
alat ini dan itulah yang akan saya rekomendasikan kepada programmer BASH. BASH adalah bahasa tanpa jenis. Ya, itu bisa melakukan bilangan bulat aritmatika, tetapi untuk floating point Anda harus menggunakan beberapa alat eksternal. SM adalah yang terbaik karena itu dibuat untuk apa.Lebih baik digunakan
awk
untuk matematika non integer. Anda dapat menggunakan fungsi utilitas bash ini:Dan menyebutnya sebagai:
sumber
awk
danbc
dalam skrip shell adalah praktik standar sejak zaman kuno, saya akan mengatakan beberapa fitur tidak pernah ditambahkan ke cangkang karena mereka tersedia dalam awk, bc dan alat Unix lainnya. Tidak perlu untuk kemurnian dalam skrip shell.exit
agar Awk mengkomunikasikan hasilnya kembali ke shell dengan cara yang layak dan dapat dibaca mesin.if awk -v n1="123.456" -v n2="3.14159e17" 'BEGIN { exit (n1 <= n2) }' /dev/null; then echo bigger; else echo not; fi
... meskipun perhatikan bagaimana kondisinya terbalik (status keluar 0 berarti berhasil ke shell).python
. Anda telahperl
menginstal secara default di banyak sistem Linux / Unix .. bahkanphp
jugaawk
solusi lebih kuat dalam kasus saya daripada satu denganbc
yang kembali hasil yang salah untuk alasan saya tidak mendapatkan.Solusi bash murni untuk membandingkan pelampung tanpa notasi eksponensial, memimpin atau mengekor nol:
Urutan operator logis penting . Bagian integer dibandingkan sebagai angka dan bagian fraksional sengaja dibandingkan sebagai string. Variabel dibagi menjadi bilangan bulat dan bagian menggunakan metode ini .
Tidak akan membandingkan pelampung dengan bilangan bulat (tanpa titik).
sumber
Anda dapat menggunakan awk dikombinasikan dengan bash jika kondisinya, awk akan mencetak 1 atau 0 dan itu akan ditafsirkan oleh jika klausa dengan benar atau salah .
sumber
if (( $(echo $d1 $d2 | awk '{if ($1 > $2) print 1;}') )); then echo "yes"; else echo "no"; fi
waspadalah saat membandingkan angka yang merupakan versi paket, seperti memeriksa apakah grep 2.20 lebih besar dari versi 2.6:
Saya memecahkan masalah dengan fungsi shell / awk tersebut:
sumber
dpkg --compare-versions
seringkali berguna. Ini memiliki logika penuh untuk membandingkan versi paket Debian yang dibangun di dalamnya, yang lebih kompleks dari sekadarx.y
.Tentu saja, jika Anda tidak benar-benar membutuhkan aritmatika floating-point, cukup aritmatika pada misalnya nilai dolar di mana selalu ada tepat dua digit desimal, Anda mungkin hanya menjatuhkan titik (secara efektif mengalikan dengan 100) dan membandingkan bilangan bulat yang dihasilkan.
Ini jelas mengharuskan Anda untuk memastikan bahwa kedua nilai memiliki jumlah tempat desimal yang sama.
sumber
Saya menggunakan jawaban dari sini dan menempatkannya dalam suatu fungsi, Anda dapat menggunakannya seperti ini:
Setelah dipanggil,
echo $result
akan1
dalam kasus ini, jika tidak0
.Fungsi:
Atau versi dengan output debug:
Simpan saja fungsi dalam
.sh
file yang terpisah dan sertakan seperti ini:sumber
Saya memposting ini sebagai jawaban untuk https://stackoverflow.com/a/56415379/1745001 ketika sudah ditutup sebagai duplikat dari pertanyaan ini jadi ini dia sebagaimana berlaku di sini juga:
Untuk kesederhanaan dan kejelasan, gunakan awk untuk perhitungan karena ini adalah alat UNIX standar dan kemungkinan besar akan hadir sebagai bc dan lebih mudah untuk bekerja dengan sintaksis.
Untuk pertanyaan ini:
dan untuk pertanyaan lain yang ditutup sebagai duplikat dari yang ini:
sumber
awk
dan alat-alat seperti itu (saya menatap Andased
...) harus diturunkan ke tong sampah proyek lama, dengan kode yang semua orang terlalu takut untuk disentuh karena ditulis dalam bahasa yang tidak pernah dibaca.Atau Anda adalah proyek yang relatif jarang yang perlu memprioritaskan optimasi penggunaan CPU daripada optimasi pemeliharaan kode ... dalam hal ini, teruskan.
Namun, jika tidak, mengapa tidak hanya menggunakan sesuatu yang dapat dibaca dan eksplisit, seperti
python
? Rekan coders dan diri Anda di masa depan akan berterima kasih. Anda dapat menggunakanpython
sebaris dengan bash sama seperti yang lainnya.sumber
not(...)
alih-alih0 if ... else 1
awk '${print $5}' ptpd_log_file | perl -ne '$_ > 0.000100 && print' > /tmp/outfile
. Peasy mudah. Setiap bahasa memiliki tempatnya.python -c "import sys; sys.exit(0 if float($num1) < float($num2) else 1)"
adalah sederhanaawk "BEGIN{exit ($num1 > $num2 ? 0 : 1)}"
.Skrip ini dapat membantu tempat saya memeriksa apakah
grails
versi yang diinstal lebih besar dari minimum yang diperlukan. Semoga ini bisa membantu.sumber
sumber
silakan periksa kode yang diedit di bawah ini: -
ini bekerja dengan baik.
sumber
Solusi yang mendukung semua notasi yang mungkin, termasuk notasi ilmiah dengan eksponen huruf besar dan kecil (misalnya,
12.00e4
):sumber
Gunakan cangkang korn, di bash Anda mungkin harus membandingkan bagian desimal secara terpisah
sumber
Menggunakan bashj ( https://sourceforge.net/projects/bashj/ ), sebuah bash mutan dengan dukungan java, Anda cukup menulis (dan ini IS mudah dibaca):
Tentu saja bashj bash / java hybridation menawarkan lebih banyak ...
sumber
Bagaimana dengan ini? = D
sumber
exit 0
melaporkan kebenaran danexit 1
untuk kembali salah; maka Anda dapat menyederhanakan ke elegan luar biasaif awk 'BEGIN { exit (ARGV[1] >= ARGV[2]) ? 0 : 1 }' "$VAL_TO_CHECK" 1; then
... (masih lebih elegan jika Anda merangkum skrip Awk dalam fungsi shell).