2010-12-27 10 views
93

GNU bash (sürüm 4.0.35 (1) -elease (x86_64-suse-linux-gnu) kullanarak, Normal İfadeler ile bir testi iptal etmek istiyorum.Örneğin, PATH'a koşullu olarak bir yol eklemek istiyorum değişken, yol zaten orada olduğu gibi değilse: orada bunu yapmak için bir milyon yolu vardır ancak koşullu bir şekilde ortadan kalkacağı eğer ne öğrenmek istiyorum gibi eminimnasıl bash komut düzenli ifadeler ile bir test inkâr edersiniz?

TEMP=/mnt/silo/bin 
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi 
TEMP=/mnt/silo/Scripts: 
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi 
TEMP=/mnt/silo/local/bin 
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi 
export PATH 

(hatalı) 'de:!

TEMP=/mnt/silo/bin 
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi 
TEMP=/mnt/silo/Scripts: 
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi 
TEMP=/mnt/silo/local/bin 
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi 
export PATH 

Teşekkür

cevap

98

Sen doğru, sadece ! ve parantez içindeki Ayrıca ünlem koyabilirsiniz [[

+9

Oye vey! Sadece perl'in galaksiler arası özel karakter çılgınlığını güvenle savunduğumda, kendimi bash uzayında (yerleştirme) kaybettiğimi buldum! (Benim bağırsağımı bir piton gibi sıkmaktan korkuyorum.) Teşekkürler! –

6

Evet, testi zaten SiegeX'un işaret ettiği gibi reddedebilirsiniz.

Ancak bunun için normal ifadeleri kullanmaması gerektiğini - Yolunuz özel karakterler başarısız olabilir. Bunun yerine bu deneyin:

[[ ":$PATH:" != *":$1:"* ]] 

(Source)

+1

örn için "/ bin" eklemek için başarısız (yanlışlıkla alt dizeleri maç olmayacak bu formu kullanmak için bir başka neden Çünkü "/ usr/bin" zaten var. –

+0

Solda iki nokta üst üste Bana istediğim ankrajı nasıl verdiğini anlamak için biraz zaman aldı. Araştırılacak dizeye materyal ekleyerek paterni küçültme fikri hatırlamaya değerdir. Yoldaki özel karakterlerin neden regex çözümünü bozacağını değil, bash pattern çözümünü anlayacağını anlamıyorum. Bana bir örnek verebilirmisin? –

+0

Bunun her durumda güvenilir şekilde çalışacağını düşünmüyorum. Üstün IMHO Regex eşleşen –

80

if ! [[ gibi noktası arasında bir boşluk koymuştu:

if [[ ! $PATH =~ $temp ]] 

ancak yanlış pozitif azaltmak için desen demirlemek olmalıdır:Başlamadan önce ya da sonunda bir kolonun önünde ya da sonunda (ya da her ikisinde) bir eşleşme arar. Kabuk değişkenleriyle isim çarpışma olasılığını azaltmak için küçük harf veya karma büyük harf değişken adlarını alışkanlık olarak kullanmanızı öneririm.

+0

Ah, sabitleme hakkında hatırlatmalar için teşekkürler. Şimdiye kadar gördüğüm tavsiye büyük harf kullanmak olduğundan, küçük harfli veya karışık değişken isimleri kullanma fikri bir bash başlangıççı için kafa karıştırıcıdır. Yaptığınız noktayı anlıyorum, ancak yemek kitabımdan (benim anlayışımı) rahatça sapmak için yeterince bash betik örnekleri görmedim. –

+3

@anyoneis bu konuda bize güveniyor.Kullanıcı tanımlı büyük harfli değişkenlerin kullanılmasından kaçınılmalıdır. Bash'taki tüm değişkenler '$' ile genişletilir, dolayısıyla onları öne çıkarmak için büyük harf kullanmanın bir nedeni yoktur. – SiegeX

+0

Eğer [[! $ foo = ~ bar]] 'den daha güvenli! [[$ foo = ~ bar]], çünkü 'if' için daha fazla koşul getirmeyi kolaylaştırır – CTodea

15

güvenli yolu koymaktır! Böyle [[ ]] içinde regex olumsuzlama için:

if [[ ! ${STR} =~ YOUR_REGEX ]]; then 

aksi takdirde belirli sistemlerde başarısız olabilir.

0

Böyle durumlarda şartlı operatörlerini kullanmadan kod basitleştirmek istiyorum:

TEMP=/mnt/silo/bin 
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP