Bashta tamsayı için bağımsız değişken dizesi


74

Bir argümanı aritmetik işlem yapmak için bir tam sayıya nasıl dönüştüreceğinizi bulmaya çalışın ve şunu yazdırın addOne.sh:

echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1

Sorunuzu biçimlendirmeye çalışıyorum, ancak bir şekilde belirsizliğini koruyor. printf "1 + %s\n" $1 won't do ?
Archemar

Yanıtlar:


88

Bash'te "aritmetik işlem yapmak için bir argümanı bir tam sayıya dönüştürmez". Bash'te, değişkenler bağlama göre tamsayı veya dizge olarak değerlendirilir.

Aritmetik gerçekleştirmek için, aritmetik genişleme operatörünü çağırmalısınız $((...)). Örneğin:

$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3

veya genellikle tercih edilir:

$ echo "$((a + 1))"
3

Bash'ın (ksh93, zsh veya yash'ın aksine) yalnızca tamsayı aritmetiği yaptığını bilmelisiniz . Kayan nokta numaralarınız (ondalık sayılar) varsa, yardımcı olacak başka araçlar da vardır. Örneğin, bcşunları kullanın :

$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14

Veya bash yerine kayan nokta aritmetik destekli bir kabuk kullanabilirsiniz:

zsh> echo $((3.14 + 1))
4.14

Eğer dizelerin ne olduğunu bilmiyorsanız $ (()) veya (()) kullanmak güvenli değildir (kullanıcı girişi gibi). Şunu düşünün: foo = foo ((foo + = 0)) Bu, foo'yu özyinelemeli bir şekilde değerlendirmeye çalışırken komut dosyasını çökertecektir. Foo = foo foo = $ ((foo + 0)): ile aynı
sanat

12

Başka türlü, kullanabilirsiniz expr

Ör:

$ version="0002"
$ expr $version + 0
2
$ expr $version + 1
3

10

Olarak bash, kullanmakta Tamsayıya şey dönüştürme yapabilirsiniz Printf -v :

printf -v int '%d\n' "$1" 2>/dev/null

Kayan sayı tam sayıya dönüştürülürken, herhangi bir sayı sayı gibi görünmüyor, sayı 0'a dönüştürülüyor. e

Örnek:

$ printf -v int '%d\n' 123.123 2>/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' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1

2
Bu olmadan diğer kabuklarda printf -vkomut değişikliği ile elde edilebilir:int="$(printf '%d' 123.123 2>/dev/null)"
Adrian Günter

2
Bu bash çalışmıyor.
Michael Martinez,

@MichaelMartinez emin misiniz? Hangi versiyonunu bashkullandın?
Ocak'ta cuonglm

GNU bash, sürüm 4.2.46 (1) - yayın (x86_64-redhat-linux-gnu)
Michael Martinez

5

Son zamanlarda benzer bir durum, hem Linux hem de OSX ortamlarında çalışacak bash scriptleri geliştirirken ortaya çıktı. OSX'teki bir komutun sonucu, sonuç kodunu içeren bir dize döndürdü; yani " 0",. Tabii ki, bu aşağıdaki durumda doğru bir şekilde test edemedi:

if [[ $targetCnt != 0 ]]; then...

Çözüm, sonucu @ John1024'ün yanıtladığı gibi bir tamsayıya zorlamak (yani 'dönüştürmek') ve beklendiği gibi çalışmasını sağlamaktı:

targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...

3
==Vb de [[(ayrıca [aka test) dize karşılaştırma yapmak. Aritmetik karşılaştırma için farklı operatörler vardır [[ $targetcnt -ne 0 ]]; Koşullu İfadeler altındaki manpage'e (veya info) bakınız. Boşlukları özel olarak kesmek için, varsayılan sözcük ayırma (içinde yapılmamıştır ) elde etmek için genellikle [değişken olmayan genişlemeyle kullanabilirsiniz , ancak genel olarak bu yaklaşım sizi tehlikeye sokar. [ $targetcnt == 0 ][[
dave_thompson_085

-2

renk kodlarına dikkat edin, izlemeyecek olsalar bile ( -x) görünmeyecekler, onu ne verecekti ki, bir sayı olması gereken dizginin nasıl yazdırırsanız yazsın tırnaklara sarılmış olması.


1
Oyunuzu verdim, cevabınızı biraz belirsiz buluyorum. Belki de betiğin düzeltilmesi gerekenleri ekleyebilirsiniz?
Time4Tea

bu bash + integer + string arayışındaki en üst cevaptı, bu yüzden cevaplar arasında yer almayan bir bilgi parçası ekledim, yani stringler renk kodlarına sarıldığında neden bu gibi işlemlerin $((var+var))bile başarısız olacağı belirsiz olabilir. Gerçi siz echoveya printfher ikisi de değişiyorsa, aynı. Çıktının kaynağında renk kodlarını devre dışı bırakarak sadece onu düzeltebildiğim için düzeltmeyi bilmiyorum. İzleme günlüklerinde tespit etmek için, var='0'olması gerektiği gibi atanmış rahatsız edici değişkeni göreceksinizvar=0
yalnızca

Ne yapabilirsiniz çıktı ile renk kodlarını yok emin olmaktır sedbunu devre dışı olamazsa
untore
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.