XML dosyasında dizeyi özel karakterlerle değiştirmek için sed kullanma


5

Aynı diziyi bulmak için grep kullanmakta zorlanmama rağmen, bir XML dosyasındaki bir metin dizesini değiştirmek için zorlanıyorum. Değiştirilecek yeni dize ve eski dize çok fazla sayıda özel karakter içerdiğinden, bir ters eğik çizgi kullanmak yerine, onları değişkenlerde saklamanın en iyi olacağını düşündüm:

OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'

Dizeler beklendiği gibi depolanmış gibi görünüyor:

$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->

Grep'ing, eski dizginin XML dosyasında bulunduğunu onaylar:

$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>

Ancak aşağıdaki sed komutu hiçbir şekilde çıktı üretmez:

sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml

Burada ne kaçırdığımı bilen var mı?

Yanıtlar:


3

Kabuk değişkenlerini tek tırnak işaretleri içine koymak yorumlanmasını engeller. Bu yüzden emrinin etkisi yok.

$ echo  's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g

Böyle yazılmalıdır:

sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml

Ama sonra değişkenler yorumlanır. önce çağrı sed ve yine özel karakterler içeriyor:

$ echo  "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g

Bu sebepten dolayı sed tanımlamak için izin veren bu özel özelliğe sahiptir. s/// komut sınırlayıcıları basitçe kullanarak, örn .:

sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml

Yine de arama ifadeniz özel regex karakterleri içeriyor ve sed Bu sadece onun yeteneklerinin israfı gibi. İfadeyi şöyle yazarım:

sed -i 's/\(<.*webServiceHost.*jboss.bind.address.*>\)/<!--\1-->/' jboss-beans.xml

Elbette eşleştirme dizesini ihtiyaçlarınıza göre daha az ya da çok daha belirgin hale getirebilirsiniz. Yardımcı olabilecek başka güzel bir özellik de var. sed düzenleme işlemlerini belirli bir desenle eşleşen çizgilere daraltmanıza olanak tanır. Komutunuz şöyle görünebilir:

sed -i '/webServiceHost/ s/^\(.*\)$/<!--\1-->/' jboss-beans.xml

Ah evet, normal ifadelerde ve / veya sed'de kalıbın bir kısmını tutmak için \ 1'i kullanmayı tamamen unutmuştum. Teşekkürler! Ne yazık ki, hala devam eden biraz yanlış yorumlanmış gibi görünüyor: $ sed -i 's|(<.*webServiceHost.*jboss.bind.address.*>)|<!--\1-->|' jboss-beans.xml: -e expression #1, char 55: invalid reference \1 on s' command's RHS Ayrıca her iki parantezden önce ters eğik çizgi eklemeyi denedim ama yine çıktı alamadım.
rolinrok

@rolinrok Evet, benim hatam. Parantezlerden önce ters eğik çizgiler hakkında unuttum. 'Çıktı sorunu yok' ifadesine gelince, yorumlamak istediğiniz XML dosyasının bir bölümünü önce ve sonra bazı satırlarla belirtmek yardımcı olacaktır. Örneklerim, mülkünüzün bir çizgide yalnız olduğunu ve tüm çizginin yorumlandığını varsayıyor, ancak bu yanlış bir varsayım olabilir.
Rajish

Anladım! Test sırasında standart çıktıdaki değişimi görmeyi bekliyordum, ancak -i seçeneğini kullandığımı unuttum. Dosyayı kontrol ettikten sonra, istenen dize etrafında birden fazla yorum yapan karakter fark ettim. Tekrar teşekkürler!
rolinrok

@rolinrok Size yardım edebildiğime sevindim. Cevabı kabul edersen iyi olurdu;)
Rajish

Bitti! Gecikme için üzgünüm - Hala bir süper kullanıcı noob ve sadece şimdi anladım cevabınızı kabul etmeyi unuttum :)
rolinrok

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.