Bash'te bir değişkenin sayı olup olmadığını nasıl test edebilirim?


599

Betiğime iletilen bir argümanın bir sayı olup olmadığından nasıl emin olduğumu nasıl anlayamıyorum.

Tek yapmak istediğim şu:

test *isnumber* $1 && VAR=$1 || echo "need a number"

Herhangi bir yardım?


17
Bir kenara - kullandığınız test && echo "foo" && exit 0 || echo "bar" && exit 1yaklaşımın istenmeyen bazı yan etkileri olabilir - yankı başarısız olursa (belki de çıktı kapalı bir FD'ye), exit 0atlanır ve kod daha sonra dener echo "bar". Eğer bu konuda da başarısız olursa, &&durum başarısız olur ve çalışmaz exit 1! Gerçek kullanma ififadeleri ziyade &&/ ||beklenmedik yan etkileri daha az eğilimli olduğunu.
Charles Duffy

@CharlesDuffy Çoğu insanın sadece tüylü böcekleri takip etmek zorunda kaldıklarında gerçekten zekice düşünmeleri ... Eko'nun başarısızlığa dönüşebileceğini hiç düşünmemiştim.
Camilo Martin

6
Partiye biraz geç, ama Charles'ın yazdığı tehlikeleri biliyorum, çünkü bir süre önce de onlardan geçmek zorunda kaldım. İşte sizin için% 100 kusursuz (ve iyi okunabilir) bir çizgi: [[ $1 =~ "^[0-9]+$" ]] && { echo "number"; exit 0; } || { echo "not a number"; exit 1; }Kıvrımlı parantezler, bir alt kabukta işlerin YAPILMAMASI gerektiğini gösterir (bunun ()yerine parantezler kesinlikle kullanılır). Uyarı: Asla noktalı virgül kaçırmayın . Aksi takdirde bash, en çirkin (ve en anlamsız) hata mesajlarını yazdırmanıza neden olabilirsiniz ...
sözdizimi

5
Tırnak işaretlerini kaldırmazsanız Ubuntu'da çalışmaz. Yani olmalı[[ 12345 =~ ^[0-9]+$ ]] && echo OKKK || echo NOOO
Treviño

4
"Sayı" ile neyi kastettiğiniz konusunda daha spesifik olmanız gerekir . Bir tam sayı? Sabit nokta sayısı? Bilimsel ("e") gösterim? Gerekli bir aralık var mı (örn. 64 bit işaretsiz değer) veya yazılabilecek bir sayıya izin veriyor musunuz?
Toby Speight

Yanıtlar:


803

Bir yaklaşım aşağıdaki gibi düzenli bir ifade kullanmaktır:

re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
   echo "error: Not a number" >&2; exit 1
fi

Değer mutlaka bir tamsayı değilse, normal ifadeyi uygun şekilde değiştirmeyi düşünün; Örneğin:

^[0-9]+([.][0-9]+)?$

... veya, işaretli sayıları işlemek için:

^[+-]?[0-9]+([.][0-9]+)?$

7
Bu yaklaşım için + 1'tir, ancak ondalık sayılara dikkat edin, örneğin "1.0" veya "1,0" baskı "hatasıyla bu testi gerçekleştirin: Sayı değil".
sourcerebels

15
Ben '' exec> & 2; yankı ... '' oldukça aptalca. Just '' echo ...> & 2 ''
lhunath

5
@Ben gerçekten birden fazla eksi işaretini işlemek istiyor musunuz? Birden fazla evirmeyi doğru bir şekilde ele almak için işi yapmadıkça yapmak ^-?yerine yapardım ^-*.
Charles Duffy

4
@SandraSchlichting Gelecekteki tüm çıktıların stderr'a gitmesini sağlar. Burada sadece bir yankı olan bir nokta değil, ancak hata mesajlarının birden fazla satıra yayıldığı durumlar için girmeye alıştığım bir alışkanlık.
Charles Duffy

29
Normal ifadenin neden bir değişkene kaydedilmesi gerektiğinden emin değilim, ancak uyumluluk uğruysa bunun gerekli olduğunu düşünmüyorum. Sadece doğrudan ifadeyi geçerli olabilir: [[ $yournumber =~ ^[0-9]+$ ]].
konsolebox

284

Bashisms olmadan (System V sh'de bile çalışır),

case $string in
    ''|*[!0-9]*) echo bad ;;
    *) echo good ;;
esac

Bu, boş dizeleri ve basamak içermeyen dizeleri reddederek diğer her şeyi kabul eder.

Negatif veya kayan nokta sayıları için ek işler gerekir. Bir fikir, -/ .ilk "kötü" kalıbını hariç tutmak ve uygunsuz kullanımlarını içeren daha fazla "kötü" kalıp eklemek ( ?*-*/ *.*.*)


20
+1 - Bu, orijinal Bourne kabuğuna geri dönen deyimsel, taşınabilir bir yoldur ve glob tarzı joker karakterler için yerleşik desteğe sahiptir. Başka bir programlama dilinden geliyorsanız, ürkütücü görünüyor, ancak çeşitli alıntı sorunlarının kırılganlığı ve sonsuz geri / yan uyumluluk sorunları ile if test ...
başa çıkmaktan

6
${string#-}Negatif tamsayıları kabul etmek için ilk satırı (antika Bourne kabuklarında çalışmaz, ancak herhangi bir POSIX kabuğunda çalışır) olarak değiştirebilirsiniz.
Gilles 'SO- kötü olmayı bırak'

4
Ayrıca, bunun yüzerlere genişletilmesi kolaydır - '.' | *.*.*izin verilmeyen desenlere ekleyin ve izin verilen karakterlere nokta ekleyin. Benzer şekilde, daha önce isteğe bağlı bir işarete izin verebilirsiniz, ancak o zaman case ${string#[-+]}işareti görmezden gelmeyi tercih ederim .
tripleee

İmzalı tam sayıları işlemek için buna bakın: stackoverflow.com/a/18620446/2013911
Niklas Peter

2
@Dor Tırnaklar gerekli değildir, çünkü case komutu yine de bu sözcük üzerinde kelime bölme ve yol adı oluşturma gerçekleştirmez. (Ancak, kalıp eşleme karakterlerinin gerçek veya özel olup olmadığını belirlediğinden, kalıplardaki genişletmelerin tırnak içine alınması gerekebilir.)
jilles

193

Aşağıdaki çözüm, düzenli ifadelere gerek kalmadan Bourne gibi temel kabuklarda da kullanılabilir. Temel olarak, sayı olmayan değerleri kullanan herhangi bir sayısal değer değerlendirme işlemi, kabukta dolaylı olarak yanlış olarak kabul edilecek bir hata ile sonuçlanır:

"$var" -eq "$var"

de olduğu gibi:

#!/bin/bash

var=a

if [ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null; then
  echo number
else
  echo not a number
fi

Ayrıca $ için test edebilirsiniz? daha açık olan işlemin dönüş kodu:

[ -n "$var" ] && [ "$var" -eq "$var" ] 2>/dev/null
if [ $? -ne 0 ]; then
   echo $var is not number
fi

Standart hatanın yeniden yönlendirilmesi, bir sayı yoksa, bash'ın yazdığı "tamsayı ifadesi bekleniyor" iletisini gizlemek için vardır.

MAĞARALAR (aşağıdaki yorumlar sayesinde):

  • Ondalık noktalı sayılar değil geçerli olarak tanımlanan "Rakamlar"
  • Kullanma [[ ]]yerine [ ]iradesine her zaman için değerlendirmektrue
  • Bash olmayan kabukların çoğu bu ifadeyi her zaman şu şekilde değerlendirir: true
  • Bash'teki davranış belgelenmemiştir ve bu nedenle uyarı vermeden değişebilir
  • Değer, sayıdan sonra boşluklar içeriyorsa (örn. "1 a"), bash: [[: 1 a: syntax error in expression (error token is "a")
  • Değer var-name ile aynıysa (örneğin, i = "i"), aşağıdaki gibi hata üretir bash: [[: i: expression recursion level exceeded (error token is "i")

8
Yine de bunu tavsiye ederim (ancak boş dizelere izin vermek için belirtilen değişkenlerle), sonuç ne olursa olsun, Bash'te bir sayı olarak kullanılabilir olması garanti edilir .
l0b0

21
Tek braket kullanmaya özen gösterin; [[ a -eq a ]]true olarak değerlendirilir (her iki argüman da sıfıra dönüştürülür)
Tgr

3
Çok hoş! Bunun yalnızca bir tamsayı için çalıştığını, herhangi bir sayı için çalışmadığını unutmayın. Tam sayı olması gereken tek bir argümanı kontrol etmem gerekiyordu, bu yüzden bu iyi çalıştı:if ! [ $# -eq 1 -o "$1" -eq "$1" ] 2>/dev/null; then
haridsv

6
[Yerleşik argümanları aritmetik olarak değerlendirecek olan önemsiz sayıda mermi nedeniyle bu yönteme şiddetle tavsiye ediyorum . Bu hem ksh93 hem de mksh için geçerlidir. Ayrıca, her ikisi de dizileri desteklediğinden, kod enjeksiyonu için kolay bir fırsat vardır. Bunun yerine bir kalıp eşleşmesi kullanın.
ormaaj

3
@AlbertoZaccagni, bash'ın mevcut sürümlerinde, bu değerler sayısal bağlam kuralları ile yorumlanır, [[ ]]ancak bunun için değil [ ]. Bununla birlikte, bu davranış, bash'ın testkendi belgelerinde ve basında POSIX standardı tarafından belirtilmemiştir ; bash'ın gelecekteki sürümleri, herhangi bir belgelenmiş davranış vaadini bozmadan ksh ile eşleşecek şekilde davranışı değiştirebilir, bu nedenle mevcut davranışlarına devam etmenin güvenli olduğu garanti edilmez.
Charles Duffy

43

Bu, bir sayının negatif olmayan bir tamsayı olup olmadığını ve hem kabuktan bağımsız (yani bashisms olmadan) olup olmadığını ve yalnızca kabuk yerleşiklerini kullanıp kullanmadığını test eder:

YANLIŞ.

Bu ilk cevap (aşağıda), ilkinde değişken olmayan ilk karakter olduğu sürece içinde karakter bulunan tamsayılara izin verir.

[ -z "${num##[0-9]*}" ] && echo "is a number" || echo "is not a number";

DOĞRU .

Gibi Jilles yorumlanmış ve önerilen onun cevabını bu kabuk kalıpları kullanarak bunu yapmak için doğru bir yoldur.

[ ! -z "${num##*[!0-9]*}" ] && echo "is a number" || echo "is not a number";

5
Bu düzgün çalışmaz, bir rakamla başlayan herhangi bir dizeyi kabul eder. $ {VAR ## WORD} ve benzerlerindeki WORD öğesinin normal bir ifade değil bir kabuk deseni olduğunu unutmayın.
jilles

2
Bu ifadeyi İngilizceye çevirebilir misiniz lütfen? Gerçekten kullanmak istiyorum, ama bash sayfasını inceledikten sonra bile ona güvenecek kadar anlamıyorum.
CivFan

2
*[!0-9]*en az 1 rakam olmayan karakterle tüm dizelerle eşleşen bir desendir. değişkenin ${num##*[!0-9]*}içeriğini alıp numkalıpla eşleşen en uzun dizeyi kaldırdığımız bir "parametre genişletmesi" dir . Parametre genişletmesinin sonucu boş değilse ( ! [ -z ${...} ]), sayı olmayan bir karakter içermediğinden bir sayıdır.
mrucci

Ne yazık ki bu, bağımsız bir sayı geçerli sayı olmasa bile herhangi bir basamak varsa başarısız olur. Örneğin "exam1ple" veya "a2b".
studgeek

Her ikisi de başarısız122s :-(
Hastur

40

Hiç kimse bash'ın genişletilmiş desen eşleşmesini önermedi :

[[ $1 == ?(-)+([0-9]) ]] && echo "$1 is an integer"

5
Glenn, kaldırmak shopt -s extglobzira, (Buranın benim favori cevapları biri, upvoted o) Yayınınızdan Şartlı Yapıtlarının : okuyabilir zaman ==ve !=operatörler kullanılır, operatör sağındaki dizge bir desen olarak kabul edilir ve eşleştirilir kurallara göre aşağıda açıklanan Kalıp Eşleme sanki extglobkabuk seçeneği etkin bulundu. Umarım umursamazsın!
gniourf_gniourf

Bu bağlamda, bilmenize gerek yok shopt extglob... bu iyi bir şey!
gniourf_gniourf

Basit tamsayılar için iyi çalışır.

2
@Jdamian: haklısın, bu Bash 4.1'e eklendi (2009 sonunda piyasaya sürüldü… Bash 3.2 2006'da piyasaya sürüldü… şimdi eski bir yazılım, geçmişte sıkışmış olanlar için özür dilerim). Ayrıca, 2.02 sürümünde (1998'de piyasaya sürüldü) piyasaya sürülen extglobların <2.02 sürümünde çalışmadığını iddia edebilirsiniz ... Şimdi buradaki yorumunuz eski sürümlerle ilgili bir uyarı görevi görecek.
gniourf_gniourf

1
İçindeki değişkenler [[...]]kelime ayırmaya veya glob genişletmesine tabi değildir.
glenn jackman

26

Kabuktaki sayı biçimlerini doğrudan ayrıştırma çözümlerine şaşırdım. shell, dosya ve süreçleri kontrol etmek için bir DSL olmak üzere buna çok uygun değildir. Örneğin, biraz daha düşük sayıda ayrıştırıcı vardır:

isdecimal() {
  # filter octal/hex/ord()
  num=$(printf '%s' "$1" | sed "s/^0*\([1-9]\)/\1/; s/'/^/")

  test "$num" && printf '%f' "$num" >/dev/null 2>&1
}

'% F' değerini istediğiniz biçime değiştirin.


4
isnumber(){ printf '%f' "$1" &>/dev/null && echo "this is a number" || echo "not a number"; }
Gilles Quenot

4
@ sputnick sürümünüz orijinal işlevin doğal (ve yararlı) dönüş değeri anlamını kırar. Bunun yerine, işlevi olduğu gibi bırakın ve kullanın:isnumber 23 && echo "this is a number" || echo "not a number"
michael

4
Bu da olmamalı 2>/dev/null, bu yüzden isnumber "foo"stderr kirletmez?
gioele

4
Bash gibi modern kabukları "dosyaları ve süreçleri kontrol etmek için bir DSL" olarak adlandırmak, bundan çok daha fazlası için kullanıldığını görmezden geliyor - bazı dağıtımlar, paket yöneticilerini ve web arayüzlerini üzerine inşa etti (bu kadar çirkin). Toplu dosyalar açıklamanıza uysa da, bir değişken ayarlamak bile zor.
Camilo Martin

7
Diğer dillerdeki bazı deyimleri kopyalayarak akıllı olmaya çalışmanız komik. Ne yazık ki bu kabuklarda işe yaramıyor. Kabuklar çok özeldir ve onlar hakkında sağlam bir bilgi olmadan, kırık kod yazmanız muhtemeldir. Kodunuz bozuldu: isnumber "'a"true değerini döndürecektir. Bu, okuyacağınız POSIX spesifikasyonunda belgelenmiştir : Baştaki karakter tek tırnak veya çift tırnak ise, değer tek tırnak veya çift tırnaktan sonraki karakterin temel kod kümesindeki sayısal değer olmalıdır .
gniourf_gniourf

16

Cevaplara bakıyordum ve ... hiç kimse FLOAT sayılarını (nokta ile) düşünmediğini fark etti!

Grep kullanmak da harika.
-E genişletilmiş regexp
anlamına gelir -q sessiz anlamına gelir (yankılamaz)
-qE her ikisinin birleşimidir.

Doğrudan komut satırında test etmek için:

$ echo "32" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is: 32

$ echo "3a2" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is empty (false)

$ echo ".5" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer .5

$ echo "3.2" | grep -E ^\-?[0-9]?\.?[0-9]+$  
# answer is 3.2

Bir bash betiğinde kullanma:

check=`echo "$1" | grep -E ^\-?[0-9]*\.?[0-9]+$`

if [ "$check" != '' ]; then    
  # it IS numeric
  echo "Yeap!"
else
  # it is NOT numeric.
  echo "nooop"
fi

JUST tam sayılarını eşleştirmek için şunu kullanın:

# change check line to:
check=`echo "$1" | grep -E ^\-?[0-9]+$`

Awk ile triple_r ve tripleee kullanan çözümler şamandıralarla çalışır.
Ken Jackson

Bunun için teşekkürler ve çok iyi bir nokta! Çünkü soru aslında sadece bir tam sayı değil , bir sayı olup olmadığını nasıl kontrol edeceğidir.
Tanasis

Ben de teşekkür ederim Tanasis! Hep birbirimize yardım edelim.
Sergio Abreu

12

@Mary için bir takip. Ancak yeterli temsilcim olmadığı için bunu bu gönderiye yorum olarak gönderemedim. Her neyse, işte kullandığım şey:

isnum() { awk -v a="$1" 'BEGIN {print (a == a + 0)}'; }

Bağımsız değişken bir sayı ise işlev "1" döndürür, aksi takdirde "0" döndürür. Bu, tamsayıların yanı sıra şamandıralar için de geçerlidir. Kullanımı şöyle bir şeydir:

n=-2.05e+07
res=`isnum "$n"`
if [ "$res" == "1" ]; then
     echo "$n is a number"
else
     echo "$n is not a number"
fi

4
Bir sayı yazdırmak bir çıkış kodu ayarlamaktan daha az yararlıdır. 'BEGIN { exit(1-(a==a+0)) }'grok biraz zor ama doğru veya tıpkı false döndüren bir işlev kullanılabilir [, grep -qvb
tripleee

9
test -z "${i//[0-9]}" && echo digits || echo no no no

${i//[0-9]}değerindeki herhangi bir rakamı $iboş bir dize ile değiştirir, bkz man -P 'less +/parameter\/' bash.-zsonuçta elde edilen dizginin uzunluğu sıfır olup olmadığını kontrol eder.

$iboşken davanın hariç tutulmasını istiyorsanız , aşağıdaki yapılardan birini kullanabilirsiniz:

test -n "$i" && test -z "${i//[0-9]}" && echo digits || echo not a number
[[ -n "$i" && -z "${i//[0-9]}" ]] && echo digits || echo not a number

Başparmak özellikle man -P 'less +/parameter\/' bashparçası için. Her gün yeni bir şeyler öğrenmek. :)
David

@sjas Sorunu çözmek için kolayca \-normal ifade ekleyebilirsiniz . [0-9\-\.\+]Kayan ve işaretli sayıları hesaplamak için kullanın .
user2683246

@sjas tamam, benim hatam
user2683246

@sjasecho $i | python -c $'import sys\ntry:\n float(sys.stdin.read().rstrip())\nexcept:\n sys.exit(1)' && echo yes || echo no
user2683246

9

Benim sorunum için, sadece bir kullanıcının yanlışlıkla bazı metin girmemesini sağlamak için gerekli böylece basit ve okunabilir tutmaya çalıştım

isNumber() {
    (( $1 )) 2>/dev/null
}

Man sayfasına göre bu istediğim şeyi yapıyor

İfadenin değeri sıfır değilse, dönüş durumu 0'dır.

"Sayı olabilir" dizeleri için kötü hata iletileri önlemek için Hata çıktı yoksay

$ (( 2s ))
bash: ((: 2s: value too great for base (error token is "2s")

Bu daha çok isInteger gibidir. Ama harika teşekkürler!
Naheel

8

Eski bir soru, ama sadece çözümümü ele almak istedim. Bu garip bir kabuk hilesi gerektirmez veya sonsuza kadar var olmayan bir şeye güvenmez.

if [ -n "$(printf '%s\n' "$var" | sed 's/[0-9]//g')" ]; then
    echo 'is not numeric'
else
    echo 'is numeric'
fi

Temel olarak girişteki tüm basamakları kaldırır ve sıfır uzunluklu olmayan bir dize bırakılırsanız sayı değildir.


Bu boş kalmaz var.
gniourf_gniourf

Veya sondaki yeni satırları veya benzerleri olan değişkenler için $'0\n\n\n1\n\n\n2\n\n\n3\n'.
gniourf_gniourf

7

Henüz yorum yapamam, bu yüzden bash desen eşleşmesini kullanarak glenn jackman'ın cevabına bir uzantı olan kendi cevabımı ekleyeceğim.

Benim asıl ihtiyacım sayıları tanımlamak, tamsayıları ve kayan noktaları ayırt etmekti. İşlev tanımları:

function isInteger() {
    [[ ${1} == ?(-)+([0-9]) ]]
}

function isFloat() {
    [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}

İstediğim gibi çalıştığım kalıpları doğrulamak için birim testi (shUnit2 ile) kullandım:

oneTimeSetUp() {
    int_values="0 123 -0 -123"
    float_values="0.0 0. .0 -0.0 -0. -.0 \
        123.456 123. .456 -123.456 -123. -.456
        123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
        123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
        123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
}

testIsIntegerIsFloat() {
    local value
    for value in ${int_values}
    do
        assertTrue "${value} should be tested as integer" "isInteger ${value}"
        assertFalse "${value} should not be tested as float" "isFloat ${value}"
    done

    for value in ${float_values}
    do
        assertTrue "${value} should be tested as float" "isFloat ${value}"
        assertFalse "${value} should not be tested as integer" "isInteger ${value}"
    done

}

Notlar: isFloat deseni, ondalık nokta ( @(.,)) ve E sembolü ( @(Ee)) hakkında daha toleranslı olacak şekilde değiştirilebilir . Birim testlerim yalnızca tamsayı veya kayan noktalı değerleri test eder, ancak geçersiz girdi içermez.


Maalesef, düzenleme işlevinin nasıl kullanılması gerektiğini anlamadım.
3ronco

6

Bunu denemek istiyorum:

printf "%g" "$var" &> /dev/null
if [[ $? == 0 ]] ; then
    echo "$var is a number."
else
    echo "$var is not a number."
fi

Not: Bu, nan ve inf'yi sayı olarak tanır.


2
pixelbeat'ın cevabının kopyası ya da belki de yorum olarak daha uygun ( %fkullanımı muhtemelen daha iyidir)
michael

3
Önceki durum kodunu kontrol etmek yerine, neden sadece ifkendi başına yazmıyorsunuz? İşte ifbu ...if printf "%g" "$var" &> /dev/null; then ...
Camilo Martin

3
Bunun başka uyarıları var. Boş dizeyi ve dizeleri doğrular 'a.
gniourf_gniourf

6

@Charles Dufy ve diğerleri tarafından açık bir cevap verilmiştir. Saf bir bash çözümü aşağıdakileri kullanıyor olabilir:

string="-12,345"
if [[ "$string" =~ ^-?[0-9]+[.,]?[0-9]*$ ]]
then
    echo $string is a number
else
    echo $string is not a number
fi

Gerçel sayılar için sayı tabanı noktasından önce bir sayı olması zorunlu değildir. .

Kayan sayıları ve bilimsel gösterimi daha kapsamlı bir şekilde desteklemek için (C / Fortran'daki birçok program veya şamandıra bu şekilde dışa aktarılacaktır), bu satıra yararlı bir ek aşağıdakiler olacaktır:

string="1.2345E-67"
if [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]?-?[0-9]+$ ]]
then
    echo $string is a number
else
    echo $string is not a number
fi

Böylece, belirli bir tür arıyorsanız, sayı türlerini ayırt etmenin bir yoluna yol açar:

string="-12,345"
if [[ "$string" =~ ^-?[0-9]+$ ]]
then
    echo $string is an integer
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*$ ]]
then
    echo $string is a float
elif [[ "$string" =~ ^-?[0-9]*[.,]?[0-9]*[eE]-?[0-9]+$ ]]
then
    echo $string is a scientific number
else
    echo $string is not a number
fi

Not: Ondalık ve bilimsel gösterim için sözdizimsel gereklilikleri sıralayabiliriz. Bunlardan biri virgülün taban noktası olarak ve "." Daha sonra böyle bir sayı tabanı noktası olması gerektiğini söyleyebiliriz. Bir [Ee] şamandıra içinde iki +/- işareti olabilir. Aulu'nun çalışmasından birkaç kural daha öğrendim ve '' '-' '-E-1' '0-0' gibi kötü dizelere karşı test ettim. İşte tutunuyor gibi görünüyor regex / substring / ifade araçları:

parse_num() {
 local r=`expr "$1" : '.*\([.,]\)' 2>/dev/null | tr -d '\n'` 
 nat='^[+-]?[0-9]+[.,]?$' \
 dot="${1%[.,]*}${r}${1##*[.,]}" \
 float='^[\+\-]?([.,0-9]+[Ee]?[-+]?|)[0-9]+$'
 [[ "$1" == $dot ]] && [[ "$1" =~ $float ]] || [[ "$1" =~ $nat ]]
} # usage: parse_num -123.456

6
[[ $1 =~ ^-?[0-9]+$ ]] && echo "number"

-Negatif sayılar eklemeyi unutmayın !


Bash'ın minimum sürümü nedir? Ben sadece bash: koşullu ikili operatör beklenen bash: sözdizimi hatası beklenmedik belirteci `` ~ ~ yakın
Paul Hargreaves

1
@PaulHargreaves =~en azından bash 3.0'a kadar vardı.
Gilles 'SO- kötü olmayı kes'

@PaulHarg muhtemelen ilk işleneninizle ilgili bir sorun yaşadığınızı gösterir, örneğin çok fazla tırnak işareti veya benzeri
Joshua Clayton

@JoshuaClayton Sürümü sordum, çünkü hala sahip olduğumuz ve hala desteklemeyen bir Solaris 7 kutusunda çok eski bir bash = ~
Paul Hargreaves

6

Bunu kullanarak elde edilebilir grep konusu değişkenin genişletilmiş bir normal ifadeyle eşleşip eşleşmediğini görmek için .

Test tamsayısı 1120:

yournumber=1120
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
    echo "Valid number."
else
    echo "Error: not a number."
fi

Çıktı: Valid number.

Tam sayı olmayan testi 1120a:

yournumber=1120a
if echo "$yournumber" | grep -qE '^[0-9]+$'; then
    echo "Valid number."
else
    echo "Error: not a number."
fi

Çıktı: Error: not a number.


açıklama

  • grep, -EAnahtar bize genişletilmiş düzenli ifade kullanmanızı sağlar '^[0-9]+$'. Bu normal ifade, değişkenin yalnızca değişkenin başından sonuna kadar sıfırdan dokuza kadar []sayı içermesi ve en azından0-9^$+ bir karakter .
  • grep, -qSessiz anahtarı bir şey bulur olsun veya olmasın herhangi bir çıkış kapanır.
  • ifçıkış durumunu kontrol eder grep. Çıkış durumu 0başarı anlamına gelir ve daha büyük bir şey hata anlamına gelir. grepKomut bir çıkış durumu vardır 0bir eşleşme bulursa ve 1öyle değil zaman;

Yani içinde, hep birlikte koyarak ifbiz testte echodeğişken $yournumberve |bunun için boru grepile hangi -qsessizce maçları anahtarı -Egenişletilmiş düzenli ifade '^[0-9]+$'ifadesini. Çıkış durumu grepolacak 0eğer grepbaşarılı ve bir eşleşme tespit 1doğru değilse. Eğer eşleşmeyi başarırsak, biz echo "Valid number.". Eğer eşleşmezse, biz echo "Error: not a number.".


Şamandıralar ve Çiftler İçin

Normal ifadeyi '^[0-9]+$'yerine'^[0-9]*\.?[0-9]+$' yüzen veya çiftlerde için.

Test şamandırası 1120.01:

yournumber=1120.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
    echo "Valid number."
else
    echo "Error: not a number."
fi

Çıktı: Valid number.

Test şamandırası 11.20.01:

yournumber=11.20.01
if echo "$yournumber" | grep -qE '^[0-9]*\.?[0-9]+$'; then
    echo "Valid number."
else
    echo "Error: not a number."
fi

Çıktı: Error: not a number.


Negatifler için

Negatif tamsayılara izin vermek için, normal ifadeyi olarak '^[0-9]+$'değiştirin '^\-?[0-9]+$'.

Negatif dalgalanmalara veya iki katına izin vermek için, normal ifadeyi olarak '^[0-9]*\.?[0-9]+$'değiştirin '^\-?[0-9]*\.?[0-9]+$'.


Haklısın, @CharlesDuffy. Teşekkürler. Cevabı temizledim.
Joseph Shih

Yine mi, @CharlesDuffy. Sabit!
Joseph Shih

1
LGTM; as-editited yanıtı + 1'im var. Bu noktada farklı yapacağım tek şey doğruluktan ziyade sadece fikir meselesidir (f / e, [-]yerine \-ve [.]yerine kullanmak \.biraz daha ayrıntılıdır, ancak bu, dizelerinizin ters eğik çizgilerin tüketildiği bir bağlamda kullanılır).
Charles Duffy

4

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_04_03.html

Ayrıca bash'ın karakter sınıflarını da kullanabilirsiniz.

if [[ $VAR = *[[:digit:]]* ]]; then
 echo "$VAR is numeric"
else
 echo "$VAR is not numeric"
fi

Sayısal olarak boşluk, ondalık nokta ve kayan nokta için "e" veya "E" yer alır.

Ancak, bir C stili onaltılık sayı belirtirseniz, yani "0xffff" veya "0XFFFF" belirtirseniz, [[: digit:]] true değerini döndürür. Burada bir tuzak biraz, bash "0xAZ00" gibi bir şey yapmanıza izin verir ve hala bir rakam olarak saymak (16 dışında üsler için 0x gösterimi kullanmanıza izin veren GCC derleyicileri tuhaf garip değil mi ??? )

Onaltılık sayıları kabul etmek istemiyorsanız, girişinizin tamamen güvenilmezse sayısal olup olmadığını test etmeden önce "0x" veya "0X" için test etmek isteyebilirsiniz. Bu şu şekilde gerçekleştirilebilir:

if [[ ${VARIABLE:1:2} = "0x" ]] || [[ ${VARIABLE:1:2} = "0X" ]]; then echo "$VAR is not numeric"; fi

17
[[ $VAR = *[[:digit:]]* ]]değişken bir tamsayı değilse , bir sayı içeriyorsa true değerini döndürür .
glenn jackman

[[ "z3*&" = *[[:digit:]]* ]] && echo "numeric"yazdırır numeric. Bash versiyonunda test edilmiştir 3.2.25(1)-release.
Jdamian

1
@ultraswadable, çözümünüz, en azından bir rakamı çevreleyen (veya içermeyen) diğer karakterlerle çevrelenen dizeleri algılar. İndirdim.
Jdamian

Açıkçası doğru yaklaşım bu nedenle bunu tersine çevirmek ve kullanmaktır[[ -n $VAR && $VAR != *[^[:digit:]]* ]]
eschwartz

@eschwartz, çözümünüz negatif sayılarla çalışmıyor
Angel

4

En basit yol, rakam olmayan karakterler içerip içermediğini kontrol etmektir. Tüm basamak karakterlerini hiçbir şeyle değiştirmezsiniz ve uzunluğu kontrol edersiniz. Uzunluk varsa, bu bir sayı değildir.

if [[ ! -n ${input//[0-9]/} ]]; then
    echo "Input Is A Number"
fi

2
Negatif sayıları ele almak daha karmaşık bir yaklaşım gerektirir.
Andy

... ya da isteğe bağlı olumlu bir işaret.
üçlü

@tripleee Nasıl yapılacağını biliyorsanız yaklaşımınızı görmek istiyorum.
Andy

4

Ben son zamanlarda bu kurcalamak zorunda olduğu gibi ve ünite ile karttu's yaklaşım gibi en test. Kodu revize ettim ve başka çözümler de ekledim, sonuçları görmek için kendiniz deneyin:

#!/bin/bash

    # N={0,1,2,3,...} by syntaxerror
function isNaturalNumber()
{
 [[ ${1} =~ ^[0-9]+$ ]]
}
    # Z={...,-2,-1,0,1,2,...} by karttu
function isInteger() 
{
 [[ ${1} == ?(-)+([0-9]) ]]
}
    # Q={...,-½,-¼,0.0,¼,½,...} by karttu
function isFloat() 
{
 [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]
}
    # R={...,-1,-½,-¼,0.E+n,¼,½,1,...}
function isNumber()
{
 isNaturalNumber $1 || isInteger $1 || isFloat $1
}

bools=("TRUE" "FALSE")
int_values="0 123 -0 -123"
float_values="0.0 0. .0 -0.0 -0. -.0 \
    123.456 123. .456 -123.456 -123. -.456 \
    123.456E08 123.E08 .456E08 -123.456E08 -123.E08 -.456E08 \
    123.456E+08 123.E+08 .456E+08 -123.456E+08 -123.E+08 -.456E+08 \
    123.456E-08 123.E-08 .456E-08 -123.456E-08 -123.E-08 -.456E-08"
false_values="blah meh mooh blah5 67mooh a123bc"

for value in ${int_values} ${float_values} ${false_values}
do
    printf "  %5s=%-30s" $(isNaturalNumber $value) ${bools[$?]} $(printf "isNaturalNumber(%s)" $value)
    printf "%5s=%-24s" $(isInteger $value) ${bools[$?]} $(printf "isInteger(%s)" $value)
    printf "%5s=%-24s" $(isFloat $value) ${bools[$?]} $(printf "isFloat(%s)" $value)
    printf "%5s=%-24s\n" $(isNumber $value) ${bools[$?]} $(printf "isNumber(%s)" $value)
done

Yani isNumber () tire, virgül ve üstel gösterimi içerir ve bu nedenle tamsayılarda ve kayan noktalarda TRUE değerini döndürür ; diğer yandan isFloat () , tamsayı değerlerinde FALSE değerini döndürür ve isInteger () de float üzerinde FALSE değerini döndürür. Rahatlığınız için hepsi bir astar olarak:

isNaturalNumber() { [[ ${1} =~ ^[0-9]+$ ]]; }
isInteger() { [[ ${1} == ?(-)+([0-9]) ]]; }
isFloat() { [[ ${1} == ?(-)@(+([0-9]).*([0-9])|*([0-9]).+([0-9]))?(E?(-|+)+([0-9])) ]]; }
isNumber() { isNaturalNumber $1 || isInteger $1 || isFloat $1; }

Kişisel functionolarak yararlı bir şey yapmadığı için anahtar kelimeyi kaldırırım . Ayrıca, dönüş değerlerinin kullanışlılığından emin değilim. Aksi belirtilmedikçe, işlevler son komutun çıkış durumunu döndürür, böylece returnkendiniz bir şey yapmanız gerekmez .
Tom Fenech

Güzel, gerçekten returns kafa karıştırıcı ve daha az okunabilir hale getirmek. functionAnahtar kelimeler ya da değil kullanarak daha fazla kişisel lezzet bir sorudur en azından ben biraz yer kazanmak için bir gömlek onları kaldırıldı. Teşekkür.
3ronco

Tek satırlı sürümler için yapılan testlerden sonra noktalı virgüllere ihtiyaç olduğunu unutmayın.
Tom Fenech

2
isNumber, içinde sayı olan herhangi bir dizede 'true' değerini döndürür.
DrStrangepork

@DrStrangepork Gerçekten, false_values ​​dizim bu durumda eksik. Buna bakacağım. İpucu için teşekkürler.
3ronco

4

Kullandığım İfade . Sayısal olmayan bir değere sıfır eklemeye çalışırsanız sıfırdan farklı bir değer döndürür:

if expr -- "$number" + 0 > /dev/null 2>&1
then
    echo "$number is a number"
else
    echo "$number isn't a number"
fi

Tamsayı olmayanlara ihtiyacınız varsa bc kullanmak mümkün olabilir , ancak bcaynı davranışa sahip olduğuna inanmıyorum . Sayı olmayan bir sayıya sıfır eklemek sıfır yapar ve sıfır da döndürür. Belki birleştirebilirsin bcve expr. 'A bcsıfır eklemek için kullanın $number. Cevap buysa, sıfır olmadığını doğrulamaya 0çalışın .expr$number


1
Bu oldukça kötü. Biraz daha iyi yapmak için kullanmalısınız expr -- "$number" + 0; yine de bu hala bunu yapacaktır 0 isn't a number. İtibaren man expr:Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null or 0,
gniourf_gniourf

3

Alberto Zaccagni'nin cevabını seviyorum.

if [ "$var" -eq "$var" ] 2>/dev/null; then

Önemli önkoşullar: - alt kabuklar ortaya çıkmaz - RE ayrıştırıcıları çağrılmaz - çoğu kabuk uygulaması gerçek sayı kullanmaz

Ancak $varkarmaşıksa (örn. İlişkisel dizi erişimi) ve sayı negatif olmayan bir tamsayı olacaksa (çoğu kullanım örneği), bu belki daha verimlidir?

if [ "$var" -ge 0 ] 2> /dev/null; then ..

2

Belirtilen diğer cevaplar olarak printf kullanıyorum, "% f" biçim dizgisini sağlarsanız veya "% i" printf denetimi sizin için yapar. Kontrolleri yeniden icat etmekten daha kolay, sözdizimi basit ve kısadır ve printf her yerde bulunur. Bu yüzden bence iyi bir seçim - ayrıca bir dizi şeyi kontrol etmek için aşağıdaki fikri kullanabilirsiniz, sadece sayıları kontrol etmek için yararlı değildir.

declare  -r CHECK_FLOAT="%f"  
declare  -r CHECK_INTEGER="%i"  

 ## <arg 1> Number - Number to check  
 ## <arg 2> String - Number type to check  
 ## <arg 3> String - Error message  
function check_number() { 
  local NUMBER="${1}" 
  local NUMBER_TYPE="${2}" 
  local ERROR_MESG="${3}"
  local -i PASS=1 
  local -i FAIL=0   
  case "${NUMBER_TYPE}" in 
    "${CHECK_FLOAT}") 
        if ((! $(printf "${CHECK_FLOAT}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
    "${CHECK_INTEGER}") 
        if ((! $(printf "${CHECK_INTEGER}" "${NUMBER}" &>/dev/random;echo $?))); then 
           echo "${PASS}"
        else 
           echo "${ERROR_MESG}" 1>&2
           echo "${FAIL}"
        fi 
        ;;                 
                     *) 
        echo "Invalid number type format: ${NUMBER_TYPE} to check_number()." 1>&2
        echo "${FAIL}"
        ;;                 
   esac
} 

>$ var=45

>$ (($(check_number $var "${CHECK_INTEGER}" "Error: Found $var - An integer is required."))) && { echo "$var+5" | bc; }


2

Düzenli ifade vs parametre genişletme

Gibi Charles Duffy cevap çalışması, ama sadece kullanım Düzenli ifade , ve bunun yavaş olduğunu biliyorum, sadece kullanarak başka bir yol göstermek istiyorumparametre genişletme :

Yalnızca pozitif tamsayılar için:

is_num() { [ "$1" ] && [ -z "${1//[0-9]}" ] ;}

Tamsayılar için:

is_num() { 
    local chk=${1#[+-]};
    [ "$chk" ] && [ -z "${chk//[0-9]}" ]
}

Sonra yüzmek için:

is_num() { 
    local chk=${1#[+-]};
    chk=${chk/.}
    [ "$chk" ] && [ -z "${chk//[0-9]}" ]
}

İlk isteği eşleştirmek için:

set -- "foo bar"
is_num "$1" && VAR=$1 || echo "need a number"
need a number

set -- "+3.141592"
is_num "$1" && VAR=$1 || echo "need a number"

echo $VAR
+3.141592

Şimdi biraz karşılaştırma:

Charles Duffy'nin cevabına göre aynı kontrol var :

cdIs_num() { 
    local re='^[+-]?[0-9]+([.][0-9]+)?$';
    [[ $1 =~ $re ]]
}

Bazı testler:

if is_num foo;then echo It\'s a number ;else echo Not a number;fi
Not a number
if cdIs_num foo;then echo It\'s a number ;else echo Not a number;fi
Not a number
if is_num 25;then echo It\'s a number ;else echo Not a number;fi
It's a number
if cdIs_num 25;then echo It\'s a number ;else echo Not a number;fi
It's a number
if is_num 3+4;then echo It\'s a number ;else echo Not a number;fi
Not a number
if cdIs_num 3+4;then echo It\'s a number ;else echo Not a number;fi
Not a number
if is_num 3.1415;then echo It\'s a number ;else echo Not a number;fi
It's a number
if cdIs_num 3.1415;then echo It\'s a number ;else echo Not a number;fi
It's a number

Tamam sorun değil. Şimdi tüm bunları kaç kez alacak (Benim ahududu pi üzerinde):

time for i in {1..1000};do is_num +3.14159265;done
real    0m2.476s
user    0m1.235s
sys     0m0.000s

Sonra düzenli ifadelerle:

time for i in {1..1000};do cdIs_num +3.14159265;done
real    0m4.363s
user    0m2.168s
sys     0m0.000s

Yine de katılıyorum, parametre genişletmeyi kullanabildiğimde regex kullanmamayı tercih ediyorum ... RE'nin kötüye kullanılması bash betiğini yavaşlatacak
F. Hauri

Cevap düzenlendi: Gerek yok extglob(ve biraz daha hızlı)!
F. Hauri

@CharlesDuffy, Raspberry pi'mde, 1000 yineleme sürümümle 2,5 sn ve sürümünüzle 4,4 sn alacak!
F. Hauri

Bununla tartışamam. 👍
Charles Duffy

1

Negatif sayıları yakalamak için:

if [[ $1 == ?(-)+([0-9.]) ]]
    then
    echo number
else
    echo not a number
fi

Ayrıca, önce genişletilmiş globbing'in etkinleştirilmesi gerekir. Bu, varsayılan olarak devre dışı bırakılan yalnızca Bash özelliğidir.
üçlü

@tripleee genişletilmiş globbing == veya! = When the ‘==’ and ‘!=’ operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob shell option were enabled. gnu.org/software/bash/manual/bashref.html#index-_005b_005b
Badr Elmers

@BadrElmers Güncelleme için teşekkürler. Bu, Bash 3.2.57 (MacOS Mojave) sürümümde doğru olmayan yeni bir davranış gibi görünüyor. 4.4'te açıkladığınız gibi çalıştığını görüyorum.
üçlü

1

"Let" komutunu şu şekilde de kullanabilirsiniz:

[ ~]$ var=1
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=01
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s a number
[ ~]$ var=toto
[ ~]$ let $var && echo "It's a number" || echo "It's not a number"
It\'s not a number
[ ~]$ 

Ama ben bu iş parçacığında bazı cevaplar gibi "= ~" Bash 3 + operatörü kullanmayı tercih ederim.


5
Bu çok tehlikelidir. Kabuktaki doğrulanmamış aritmetiği değerlendirmeyin. Önce başka bir şekilde valide edilmelidir.
ormaaj

1
printf '%b' "-123\nABC" | tr '[:space:]' '_' | grep -q '^-\?[[:digit:]]\+$' && echo "Integer." || echo "NOT integer."

-\?Negatif tamsayıyı kabul etmiyorsanız, grep eşleştirme desenini kaldırın .


2
Açıklama eksikliği için aşağıya oy verin. Bu nasıl çalışıyor? Karmaşık ve kırılgan görünüyor ve tam olarak hangi girdileri kabul edeceği belli değil. (Örneğin, boşlukları kaldırmak çok gerekli mi? Neden? Gömülü boşluklu bir sayının, istenmeyebilecek geçerli bir sayı olduğunu söyleyecektir.)
Üçlü

1

Burada aynı şeyi, tüm parçayı ve ondalık basamakları bir nokta ile ayrılmış olarak test eden düzenli bir ifade ile yaptım.

re="^[0-9]*[.]{0,1}[0-9]*$"

if [[ $1 =~ $re ]] 
then
   echo "is numeric"
else
  echo "Naahh, not numeric"
fi

Cevabınızın neden diğer eski cevaplardan, örneğin Charles Duffy'nin cevabından temel olarak farklı olduğunu açıklayabilir misiniz? Tek bir periyodu doğruladığı için cevabınız gerçekten kırıldı.
gniourf_gniourf

burada tek periyodu anlamak için emin değilim ... beklenen bir ya da sıfır dönem .... Ama temelde farklı bir şey değil, sadece normal ifade okumak daha kolay buldum.
Jerome,

Ayrıca * kullanarak daha gerçek dünya vakaları eşleşmelidir
Jerome

Şey, boş dizeyi a=''ve yalnızca nokta içeren bir dizeyi eşleştiriyor olmanızdır, a='.'bu nedenle kodunuz biraz bozulur ...
gniourf_gniourf

0

Aşağıdakileri kullanıyorum (tamsayılar için):

## ##### constants
##
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1

## --------------------------------------
## isNumber
## check if a value is an integer 
## usage: isNumber testValue 
## returns: ${__TRUE} - testValue is a number else not
##
function isNumber {
  typeset TESTVAR="$(echo "$1" | sed 's/[0-9]*//g' )"
  [ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}

isNumber $1 
if [ $? -eq ${__TRUE} ] ; then
  print "is a number"
fi

Neredeyse doğru (boş ipi kabul ediyorsunuz) ama şaşkınlık açısından minnetle karmaşık.
Gilles 'SO- kötü olmayı bırak'

2
Hatalı: Kabul ediyorsunuz -n, vb. ( echoNedeniyle $(...)) ve sondaki yeni satırlara sahip değişkenleri kabul ediyorsunuz (nedeniyle ). Ve bu arada, printgeçerli bir kabuk komutu değil.
gniourf_gniourf

0

Benim için en pratik göründüğü için ultrasawblade'in tarifini denedim ve çalıştıramadım. Sonunda başka bir şekilde, parametre değiştirmede diğerleri gibi, bu kez regex değiştirme ile tasarladım:

[[ "${var//*([[:digit:]])}" ]]; && echo "$var is not numeric" || echo "$var is numeric"

$ Var içindeki her: digit: sınıf karakterini kaldırır ve boş bir dizeyle bırakılıp bırakılmadığımızı kontrol eder, bu da orijinalin sadece sayılar olduğunu gösterir.

Bu konuda ne gibi küçük ayak izi ve esneklik olduğunu. Bu formda yalnızca sınırlandırılmamış, temel 10 tamsayıları için çalışır, ancak diğer gereksinimlere uyacak şekilde desen eşleştirmeyi kullanabilirsiniz.


Mrucci'nin çözümünü okumak, benimkiyle neredeyse aynı görünüyor, ancak "sed tarzı" yerine normal dize değiştirme kullanıyor. Her ikisi de desen eşleştirme için aynı kuralları kullanır ve AFAIK, değiştirilebilir çözümlerdir.
ata

sedPOSIX, çözümünüz ise bash. Her ikisinin de kullanımları var
v010dya

0

Hızlı ve Kirli: En zarif yol olmadığını biliyorum, ama genellikle sadece bir sıfır ekledim ve sonucu test ettim. şöyle:

function isInteger {
  [ $(($1+0)) != 0 ] && echo "$1 is a number" || echo "$1 is not a number"
 }

x=1;      isInteger $x
x="1";    isInteger $x
x="joe";  isInteger $x
x=0x16 ;  isInteger $x
x=-32674; isInteger $x   

$ (($ 1 + 0)), 0 $ veya tamsayı DEĞİLSE bomba döndürür. Örneğin:

function zipIt  { # quick zip - unless the 1st parameter is a number
  ERROR="not a valid number. " 
  if [ $(($1+0)) != 0 ] ; then  # isInteger($1) 
      echo " backing up files changed in the last $1 days."
      OUT="zipIt-$1-day.tgz" 
      find . -mtime -$1 -type f -print0 | xargs -0 tar cvzf $OUT 
      return 1
  fi
    showError $ERROR
}

NOT: Sanırım tüm senaryo bombasını yapacak şamandıraları veya karışık türleri kontrol etmeyi hiç düşünmedim ... benim durumumda, daha fazla gitmesini istemedim. Mrucci'nin çözümü ve Duffy'nin normal ifadesiyle oynayacağım - bash çerçevesindeki en sağlam görünüyorlar ...


4
Bu, aritmetik ifadeleri kabul eder 1+1, ancak önde gelen 0s ile bazı pozitif tamsayıları reddeder (çünkü 08geçersiz bir sekizli sabittir).
Gilles 'SO- kötü olmayı bırak'

2
Bu işlem diğer sorunları vardır: 0bir sayı değil ve bu keyfi kod yerleştirme tabidir, bunu deneyin: isInteger 'a[$(ls)]'. Hata.
gniourf_gniourf

1
Ve genişlemesi $((...))alıntılanmamıştır, bir sayısal IFS=123onu değiştirir.
Isaac
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.