Saya mencoba memformat pertanyaan Anda, tetapi entah bagaimana tetap tidak jelas. printf "1 + %s\n" $1 won't do ?
Archemar
Jawaban:
89
Dalam bash, seseorang tidak "mengubah argumen menjadi integer untuk melakukan aritmatika". Dalam bash, variabel diperlakukan sebagai integer atau string tergantung pada konteksnya.
Untuk melakukan aritmatika, Anda harus memanggil operator ekspansi aritmatika $((...)). Sebagai contoh:
$ a=2
$ echo "$a + 1"2+1
$ echo "$(($a + 1))"3
atau umumnya disukai:
$ echo "$((a + 1))"3
Anda harus menyadari bahwa bash (tidak seperti ksh93, zsh atau yash) hanya melakukan aritmatika integer . Jika Anda memiliki angka floating point (angka dengan desimal), maka ada alat lain untuk membantu. Misalnya, gunakan bc:
Menggunakan $ (()) atau (()) tidak aman jika Anda tidak tahu apa string-nya (seperti input pengguna). Pertimbangkan ini: foo = foo ((foo + = 0)) Ini akan membuat crash script ketika mencoba untuk mengevaluasi foo secara rekursif. Sama dengan: foo = foo foo = $ ((foo + 0))
Di bash, Anda dapat melakukan konversi dari apa saja ke integer menggunakan printf -v :
printf -v int '%d\n'"$1"2>/dev/null
Angka mengambang akan dikonversi menjadi bilangan bulat, sementara apa pun yang tidak terlihat seperti angka akan dikonversi menjadi 0. Eksponensial akan terpotong ke angka sebelum e
Contoh:
$ printf -v int '%d\n'123.1232>/dev/null
$ printf '%d\n'"$int"123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n'"$int"0
$ printf -v int '%d\n'1e102>/dev/null
$ printf '%d\n'"$int"1
Dalam cangkang lain tanpa printf -vini dapat dicapai dengan substitusi perintah:int="$(printf '%d' 123.123 2>/dev/null)"
Adrian Günter
2
Ini tidak berfungsi dalam bash.
Michael Martinez
@MichaelMartinez Anda yakin? Versi apa yang bashAnda gunakan?
cuonglm
GNU bash, versi 4.2.46 (1) -release (x86_64-redhat-linux-gnu)
Michael Martinez
5
Situasi serupa muncul baru-baru ini ketika mengembangkan skrip bash untuk dijalankan di lingkungan Linux dan OSX. Hasil dari satu perintah di OSX mengembalikan string yang berisi kode hasil; yaitu " 0",. Tentu saja, ini gagal untuk menguji dengan benar dalam kasus berikut:
if[[ $targetCnt !=0]];then...
Solusinya adalah dengan memaksa (yaitu, 'mengkonversi') hasilnya ke integer, mirip dengan apa yang dijawab @ John1024 di atas sehingga berfungsi seperti yang diharapkan:
==dll di [[(juga [alias test) melakukan perbandingan string. Ada beberapa operator untuk perbandingan aritmatika misalnya [[ $targetcnt -ne 0 ]]; lihat halaman manual (atau info) di bawah Ekspresi Bersyarat. Untuk memangkas spasi secara spesifik, Anda dapat menggunakan [dengan ekspansi variabel yang tidak [ $targetcnt == 0 ]dikutip untuk mendapatkan penempatan kata-kata standar (TIDAK dilakukan [[) tetapi secara umum pendekatan itu membawa Anda ke dalam bahaya.
dave_thompson_085
-2
peduli dengan kode warna, bahkan dalam trace ( -x) mereka tidak akan muncul, apa yang akan memberikannya adalah bahwa string yang seharusnya nomor dibungkus dengan tanda kutip tidak peduli bagaimana Anda mencetaknya.
Terpilih, karena saya menemukan jawaban Anda agak tidak jelas. Mungkin Anda bisa menambahkan skrip apa yang harus diperbaiki?
Time4Tea
ini adalah jawaban teratas dalam mencari bash + integer + string jadi saya menambahkan sepotong informasi yang berkaitan dengan itu yang tidak termasuk di antara jawaban, yaitu ketika string dibungkus dengan kode warna mungkin tidak jelas mengapa operasi seperti $((var+var))gagal bahkan meskipun jika Anda echoatau printfkeduanya vars mereka sama. Saya tidak tahu cara memperbaikinya karena saya hanya bisa memperbaikinya dengan menonaktifkan kode warna pada sumber output. Untuk menemukannya di jejak log Anda akan melihat variabel menyinggung ditetapkan sebagai var='0'sementara itu seharusnyavar=0
untore
Yang dapat Anda lakukan adalah memastikan keluarannya tidak memiliki kode warna sedjika Anda tidak dapat menonaktifkannya
printf "1 + %s\n" $1 won't do ?
Jawaban:
Dalam bash, seseorang tidak "mengubah argumen menjadi integer untuk melakukan aritmatika". Dalam bash, variabel diperlakukan sebagai integer atau string tergantung pada konteksnya.
Untuk melakukan aritmatika, Anda harus memanggil operator ekspansi aritmatika
$((...))
. Sebagai contoh:atau umumnya disukai:
Anda harus menyadari bahwa bash (tidak seperti ksh93, zsh atau yash) hanya melakukan aritmatika integer . Jika Anda memiliki angka floating point (angka dengan desimal), maka ada alat lain untuk membantu. Misalnya, gunakan
bc
:Atau Anda dapat menggunakan shell dengan dukungan aritmatika floating point alih-alih bash:
sumber
Cara lain, Anda bisa menggunakan
expr
Ex:
sumber
Di
bash
, Anda dapat melakukan konversi dari apa saja ke integer menggunakan printf -v :Angka mengambang akan dikonversi menjadi bilangan bulat, sementara apa pun yang tidak terlihat seperti angka akan dikonversi menjadi 0. Eksponensial akan terpotong ke angka sebelum
e
Contoh:
sumber
printf -v
ini dapat dicapai dengan substitusi perintah:int="$(printf '%d' 123.123 2>/dev/null)"
bash
Anda gunakan?Situasi serupa muncul baru-baru ini ketika mengembangkan skrip bash untuk dijalankan di lingkungan Linux dan OSX. Hasil dari satu perintah di OSX mengembalikan string yang berisi kode hasil; yaitu
" 0"
,. Tentu saja, ini gagal untuk menguji dengan benar dalam kasus berikut:Solusinya adalah dengan memaksa (yaitu, 'mengkonversi') hasilnya ke integer, mirip dengan apa yang dijawab @ John1024 di atas sehingga berfungsi seperti yang diharapkan:
sumber
==
dll di[[
(juga[
aliastest
) melakukan perbandingan string. Ada beberapa operator untuk perbandingan aritmatika misalnya[[ $targetcnt -ne 0 ]]
; lihat halaman manual (atau info) di bawah Ekspresi Bersyarat. Untuk memangkas spasi secara spesifik, Anda dapat menggunakan[
dengan ekspansi variabel yang tidak[ $targetcnt == 0 ]
dikutip untuk mendapatkan penempatan kata-kata standar (TIDAK dilakukan[[
) tetapi secara umum pendekatan itu membawa Anda ke dalam bahaya.peduli dengan kode warna, bahkan dalam trace (
-x
) mereka tidak akan muncul, apa yang akan memberikannya adalah bahwa string yang seharusnya nomor dibungkus dengan tanda kutip tidak peduli bagaimana Anda mencetaknya.sumber
$((var+var))
gagal bahkan meskipun jika Andaecho
atauprintf
keduanya vars mereka sama. Saya tidak tahu cara memperbaikinya karena saya hanya bisa memperbaikinya dengan menonaktifkan kode warna pada sumber output. Untuk menemukannya di jejak log Anda akan melihat variabel menyinggung ditetapkan sebagaivar='0'
sementara itu seharusnyavar=0
sed
jika Anda tidak dapat menonaktifkannya