2016-04-14 76 views
2

Bir Oracle RAC ortamından doğru olduğundan emin olmak için bir TNS girdisinin içeriğini tnsnames.ora dosyasından yazdırmaya çalışıyorum. Geri alacaktnsnames.ora karşı regex w/grep

grep -A 4 "mydb.mydomain.com" $ORACLE_HOME/network/admin/tnsnames.ora 

:

Yani böyle bir şey yaparsanız

Benim istediğim
mydb.mydomain.com = 
(DESCRIPTION = 
    (ADDRESS = 
    (PROTOCOL = TCP)(HOST = myhost.mydomain.com)(PORT = 1521)) 
  (CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME=mydb))) 

.

export [email protected]:1521/mydb 

Yani yukarıdaki dize dışına TNS takma mydb.mydomain.com almak gerekir: Şimdi kabuk komut dosyası gibi çağrılan zaman bir ortam değişkeni harici bir program tarafından JDBC bağlantı dizesi için ayarlanan var. Birden fazla eşleşmeyi nasıl yapacağımdan emin değilim ve eşleşmeleri düzenli ifadelerle yeniden sırala ve biraz yardıma ihtiyacım var.

grep @.+: $DB_URL 

Ben

@myhost.mydomain.com: 

alacak varsayalım ama

mydb.mydomain.com 

Bu yüzden bu kısmında şaşırıp arıyorum. TNS takma adını nasıl alabilirim ve daha sonra TNS girişi için metni görüntülemek için ilk grep ile birleştirip birleştiririm?

Teşekkür


güncelleme:

@ mklement0 @Walter A - Ben senin yollarını denedik ama onlar aradığım tam olarak ne.

echo "@myhost.mydomain.com:1521/mydb" | grep -Po "@\K[^:]*" 
echo "@myhost.mydomain.com:1521/mydb" | sed 's/.*@\(.*\):.*/\1/' 
echo "@myhost.mydomain.com:1521/mydb" | cut -d"@" -f2 | cut -d":" -f1 
echo "@myhost.mydomain.com:1521/mydb" | tr "@:" "\t" | cut -f2 
echo "@myhost.mydomain.com:1521/mydb" | awk -F'[@:]' '{ print $2 }' 

Bütün bu yöntemler beni geri almak: myhost.mydomain.com

Ne aradığım aslında: mydb.mydomain.com

cevap

2

Not:
- kısalık için Aşağıdaki komutlar, dizeleri stdin'e göndermek için bash/ksh/zshhere-string sözdizimi kullanın (<<<"$var"). Kabuğunuz bunu desteklemiyorsa, bunun yerine printf %s "$var" | ... kullanın.

$DB_URL istenen dize (mydb.mydomain.com) (@myhost.mydomain.com:1521/mydb) çıkartacaktır aşağıdaki awk komut:

awk -F '[@:/]' '{ sub("^[^.]+", "", $2); print $4 $2 }' <<<"$DB_URL" 
  • -F'[@:/]' tarafından alanlara girişini bölmek awk söyler ya @ veya : veya / . Girişiniz ile bu, ilgili alanın bölümikinci alanı ($2) ve dördüncü alanı ($4) olduğu anlamına gelir.sub() çağrısı, ilk . temel bileşenini $2'dan kaldırır ve print çağrıları sonucu bir araya getirir.

hep birlikte koymak için:

domain=$(awk -F '[@:/]' '{ sub("^[^.]+", "", $2); print $4 $2 }' <<<"$DB_URL") 
grep -F -A 4 "$domain" "$ORACLE_HOME/network/admin/tnsnames.ora" 

Sen kesinlikle ara değişken $domain gerekmez, ama netlik için bunu ekledik. , literal olarak arama teriminin . gibi davranılması gerektiğini belirtmek için grep'a nasıl eklendiğini unutmayın, böylece . gibi karakterler normal ifade meta karakterleri olarak kabul edilmez.

: değişmez olarak tedaviyi sağlamak için kaçış (kabuk parameter expansion kullanılarak) . karakter -

Alternatif olarak, daha güçlü bir eşleme için, bir ^ hattın başlangıcına sabitlenir düzenli ifade ve \ kullanımı

grep -A 4 "^${domain//./\.}" "$ORACLE_HOME/network/admin/tnsnames.ora" 
+0

Son güncellemenizi gördüm ... şu an tasarlandığı şekilde çalışıyor gibi görünüyor. Teşekkürler! – dave111

+0

@ dave111: Bunu duyduğuma sevindim. Sorunuz başlamış olmak için iyi sunuldu, ancak görebildiğiniz gibi, “mydb” ve “myhost” arasındaki benzerlik, hem ben hem de Walter A'nın farkı kaçırmasına neden oldu. Kendine not: daha dikkatli okuyun. Sizin için öneri: Belki de insanların sizin sorunuzda gözden kaçırdığı şeyleri açıkça vurgulayın. – mklement0

2

Hiç sahip

# Only GNU-grep 
echo "@myhost.mydomain.com:1521/mydb" | grep -Po "@\K[^:]*" 
# or 
echo "@myhost.mydomain.com:1521/mydb" | sed 's/.*@\(.*\):.*/\1/' 
# or 
echo "@myhost.mydomain.com:1521/mydb" | cut -d"@" -f2 | cut -d":" -f1 
# or, when the string already is in a var 
echo "${DB_URL#*@}" | cut -d":" -f1 
# or using a temp var 
tmpvar="${DB_URL#*@}" 
echo "${tmpvar%:*}" 

ile bir dize bir kısmını elde edebilirsiniz @ Mklement0 zaten tarafından verildi alternatif awk, atlanan: Eğer böyle bir şey yapabileceği awk olmadan aynı yaklaşımı kullanmak istediğinizde

echo "@myhost.mydomain.com:1521/mydb" | awk -F'[@:]' '{ print $2 }' 

awk çözüm, düz ileri

echo "@myhost.mydomain.com:1521/mydb" | tr "@:" "\t" | cut -f2 

veya buradakiler nelerdir? Yeni IFS'yi sunduktan sonra girdinin ikinci kelimesini almak istiyorum. İlk ve üçüncü kelime (ler) kukla var _ (dummyvar1 ve dummyvar2 olarak adlandırılmış olabilir) yakalanır. | borusu bir alt işlem oluşturur, bu nedenle () ürününü aynı işlemde var url değerini okumak ve görüntülemek için ihtiyacınız vardır.

+0

++ Bu kadar çok seçenek göstermeniz için, ancak 'awk -F' [@:] '' {print $ 2} 'da yazabilirsiniz. – mklement0

+0

Her ikisi de başlangıçta, OP'nin sadece düz bir dize çıkarma işlemi istemediğini, ancak "myhost" un dizgeyi, ayıklanan dizgedeki giriş dizesinin _end_'inden "mydb" ile değiştirmesini istemediğimizi özledik. – mklement0

+1

Awk zaten çözüldüğü için, kullanıcı için bir uygulama olarak 'sed' veya' IFS = '@ :.' 'ile bir çözüm bırakacağım .. –