Tamsayıları karşılaştırma: aritmetik ifade veya koşullu ifade


20

Bash'de iki tamsayı koşullu ifade kullanılarak karşılaştırılabilir

arg1 OP arg2

OP biridir -eq, -ne, -lt, -le, -gt, veya -ge. Bu aritmetik ikili işleçler, arg1 sırasıyla arg2'ye eşit, eşit değil, küçük, eşit ya da küçük, eşit ya da daha büyükse true değerini döndürür . Arg1 ve arg2 pozitif veya negatif tamsayı olabilir.

veya aritmetik ifade:

<= >= < > karşılaştırma

== != eşitlik ve eşitsizlik

Neden iki tamsayıyı karşılaştırmanın iki farklı yolu var? Hangisi ne zaman kullanılır?

Örneğin, [[ 3 -lt 2 ]]koşullu ifadeyi (( 3 < 2 ))kullanır ve aritmetik ifadeyi kullanır. Karşılaştırma doğru olduğunda her ikisi de 0 döndürür

İki tamsayıyı karşılaştırırken, bu iki yöntem her zaman birbirinin yerine kullanılabilir mi? Evet ise, Bash'in neden bir yerine iki yöntemi var?


1
= != < <= > >=dizeleri karşılaştırır . 1 -eq 01but 1 != 01and 8 -lt 42but8 > 42
dave_thompson_085

Aritmetik ifadelerde aşırı yüklenirler.
Tim

1
her özelliğin ne zaman eklendiğini öğrenmek için bash changelog'larında arama yapmanız gerekir. Aritmetik ifadelerin test komutundan çok daha sonra eklendiğinden şüpheleniyorum.
glenn jackman

Dizeleri karşılaştırmak istemiyorum. @muru.
Tim

Yanıtlar:


28

Evet, iki tamsayıyı karşılaştırmanın iki farklı yolu var.

Görünüşe göre bu gerçekler bu forumda yaygın olarak kabul edilmiyor:

  1. Deyim İçinde [ ]aritmetik karşılaştırma için operatörleri -eq, -ne, -lt, -le, -gtve -ge.

    Onlar da bir test komutunun içinde ve içinde [[ ]].

    Evet bu deyimler içinde =, <vb dize operatörleri bulunmaktadır.

  2. Deyim İçinde (( ))aritmetik karşılaştırma için operatörleri ==, !=, <, <=, >, ve >=.

    Hayır, bu bir "Aritmetik genişleme" (a ile başlayan $) olarak değildir $(( )). İnsan bashında "Bileşik Komuta" olarak tanımlanır.

    Evet, "Aritmetik genişleme" ile aynı kuralları (dahili olarak) uygular, ancak çıktısı yoktur, yalnızca bir çıkış değeri vardır. Bu şekilde kullanılabilir:

if (( 2 > 1 )); then ...

Neden iki tamsayıyı karşılaştırmanın iki farklı yolu var?

Sanırım ikincisi (( ))aritmetik testler yapmak için daha basit bir yol olarak geliştirildi. Neredeyse ile aynıdır, $(( ))ancak çıktısı yoktur.

Neden iki? Peki biz iki neden aynı printf(dış ve yerleşik) ya da dört test (harici test, yerleşiği test, [ve [[). Kabuklar bu şekilde büyür, bir yıl içinde bir alanı iyileştirir, bir sonraki yıl başkalarını iyileştirir.

Hangisi ne zaman kullanılır?

Bu çok zor bir soru çünkü etkili bir fark olmamalı. Tabii ki, bir [ ]iş ve bir (( ))işin dahili olarak çalışma biçiminde bazı farklılıklar vardır , ancak: hangisi iki tamsayıyı karşılaştırmak daha iyidir? Kimse!.

İki tamsayıyı karşılaştırırken, bu iki yöntem her zaman birbirinin yerine kullanılabilir mi?

İki sayı için evet demek zorundayım.
Ancak, değişkenler, açılımlar, matematiksel işlemler için birini veya diğerini tercih etmesi gereken önemli farklılıklar olabilir. Kesinlikle her ikisinin de eşit olduğunu söyleyemem. Birincisi, (( ))sırayla birkaç matematik işlemi gerçekleştirebilir:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi

Evet ise, Bash'in neden bir yerine iki yöntemi var?

Her ikisi de faydalıysa neden olmasın?


1
=bir ödevdir ve ==aritmetik açılımlarda bir karşılaştırmadır. Soru doğru bir şekilde alıntı yapıyor. Ama cevap yanlış.
ceving

12

Tarihsel olarak, testkomut ilk önce vardı (en azından 1979'da Unix Yedinci Baskı'ya kadar ). Bu operatörler kullanılır =ve !=dizeleri karşılaştırmak ve -eq, -ne, -ltsayıları karşılaştırma vb. Örneğin test 0 = 00, yanlıştır, ancak test 0 -eq 00doğrudur. Bu sözdizimi seçildi neden bilmiyorum ama kullanmaktan kaçının olabilir <ve >kabuk yönlendirme operatörler olarak çözümlenen ederdik. testKomut birkaç yıl sonra başka bir sözdizimi var: [ … ]eşdeğerdir test ….

[[ … ]]Ki içinde koşullu sözdizimi, <ve >alıntı olmaksızın işleme olarak da kullanılabilir, ksh, daha sonra ilave edildi. Geriye dönük uyumluluğu korudu [ … ], bu yüzden aynı işleçleri kullandı, ancak dizeleri karşılaştırmak için <ve ekledi >(örneğin, [[ 9 > 10 ]]ancak [[ 9 -lt 10 ]]). Daha fazla bilgi için, bkz. Tek veya çift köşeli ayraç kullanma - bash

Aritmetik ifadeler de 1980'lerde bir zamanlar Korn kabuğundakitest komutadan sonra geldi . Unix çevrelerinde çok popüler olan C dilinin sözdizimini takip ettiler. Böylece C'nin operatörlerini kullandılar: eşitlik için, daha az veya eşit için, vb.==<=

Unix Seventh Edition'ın aritmetik ifadeleri yoktu, ancak karşılaştırma işleçleri de dahil olmak üzere tamsayı işlemleri için C benzeri bir sözdizimi uygulayan exprkomuta sahipti. Bir kabuk komut dosyası olarak, karakterler <ve >vardı mesela, kabuğundan onları korumak için teklif edilecek if expr 1 \< 2; …eşdeğerdir if test 1 -lt 2; …. Kabuğa aritmetik ifadelerin eklenmesi, expreskimiş olanların çoğunu kullandı , bu yüzden bugün iyi bilinmemektedir.

Bir sh komut dosyasında genellikle bir tamsayı değeri hesaplamak ve [ … ]tamsayıları karşılaştırmak için aritmetik ifadeler kullanırsınız .

if [ "$((x + y))" -lt "$z" ]; then 

Ksh, bash veya zsh komut dosyalarında ((…))her ikisi için de kullanabilirsiniz .

if ((x + y < z)); then 

[[ … ]]Eğer tamsayılar başka şeyler karıştığı conditionals kullanmak istiyorsanız formu yararlıdır.


1

Test man sayfasına göre, = ve! = Dize karşılaştırmaları için kullanılırken -eq, -gt, -lt, -ge, -le ve -ne ifadeleri tamsayı karşılaştırmalarıdır. Kabuk komut dosyaları yazarken bu kurala her zaman uydum ve her zaman işe yarıyor. İfadede değişkenleriniz varsa, boş bir karşılaştırma yapmaktan kaçınmak için değişkenleri bir şekilde alıntılamanız gerekebileceğini unutmayın.

Kağıt üzerinde çok düşünmeden dize / sayı karşılaştırmaları yapıyoruz. Öte yandan bir bilgisayar, 987'nin bir sayı mı yoksa bir dizi karakter mi olduğunu bilmiyor. Doğru sonucu elde etmek için bilgisayara ne yapacağını söylemek için farklı operatörlere ihtiyacınız vardır. Burada tarihin bazılarını açıklayan bazı ek bilgiler var . Esasen, değişkenler türlenmemiş ve tarihsel uyumluluk için bu şekilde kalmıştır.


Benim yazımda = ve !=aritmetik işleçler, manpage testsadece koşullu ifade işleçlerini gösterir.
Tim
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.