#begin command block
#append all lines between two addresses to hold space
sed -n -f - <<\SCRIPT file.xml
\|<tag1>|,\|</tag1>|{ H
#at last line of search block exchange hold and pattern space
\|</tag1>|{ x
#if not conditional ; clear buffer ; branch to script end
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
#do work ; print result; clear buffer ; close blocks
s?*?*?;p;s/.*//;h;b}}
SCRIPT
Yukarıdakileri yaparsanız, gösterdiğiniz veriler göz önüne alındığında, oradaki son temizleme satırından önce sed, şuna benzer bir desen alanı ile çalışmalısınız :
^\n<tag1>\n<tag2>foo</tag2>\n</tag1>$
Desen alanınızı istediğiniz zaman look ile yazdırabilirsiniz . Daha sonra \nkarakterlere hitap edebilirsiniz .
sed l <file
Her satırın çağrıldığı sedaşamada işlediğini gösterecektir l.
Sadece bunu test ettik ve daha bir ihtiyaç Yani \backslashsonra ,commailk satırda, ama aksi çalışıyor gibidir. Burada bir _sed_functioncevap koydum, bu yüzden bu cevap boyunca gösteri amaçları için kolayca çağırabilirim: (yorumlarla birlikte çalışır, ancak kısaca aşk için kaldırılır)
_sed_function() { sed -n -f /dev/fd/3
} 3<<\SCRIPT <<\FILE
\|<tag1>|,\|</tag1>|{ H
\|</tag1>|{ x
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
s?*?*?;p;s/.*//;h;b}}
#END
SCRIPT
<tag1>
<tag2>bar</tag2>
</tag1>
<tag1>
<tag2>foo</tag2>
</tag1>
FILE
_sed_function
#OUTPUT#
<tag1>
<tag2>foo</tag2>
</tag1>
Şimdi geçiş yaparız pbir için lbiz bizim senaryoyu geliştirmek ve non-op demo kaldırmak olarak nasıl dans ettiğini görebilirsiniz s?bizim son satırında bu yüzden sed 3<<\SCRIPTsadece görünüyor gibi:
l;s/.*//;h;b}}
Sonra tekrar çalıştırırım:
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
Tamam! Bu yüzden haklıydım - bu iyi bir duygu. Şimdi, liçine çektiği ancak sildiği çizgileri görmek için fırçamızı karıştıralım . Akımımızı kaldıracak lve bir tane ekleyeceğiz, !{block}böylece şöyle görünüyor:
!{l;s/.*//;h;b}
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
Silmeden hemen önce böyle görünüyor.
Size göstermek istediğim son şey H, onu oluştururken eski alan. Gösterebileceğimi umduğum birkaç anahtar kavram var. Bu yüzden son lmeşeyi tekrar kaldırıyorum Hve sonunda eski boşluğa bir göz eklemek için ilk satırı değiştiriyorum :
{ H ; x ; l ; x
_sed_function
#OUTPUT#
\n<tag1>$
\n<tag1>\n <tag2>bar</tag2>$
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
\n<tag1>$
\n<tag1>\n <tag2>foo</tag2>$
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
Heski alan çizgi döngülerinde hayatta kalır - dolayısıyla adı. Ne Tamam - yani insanlar genellikle üzerinde çelme neler Ben sıklıkta çelme - Kullandıktan sonra onu silerek ihtiyacı olmasıdır. Bu durumda sadece bir xkez değişirim, böylece tutma alanı desen alanı haline gelir ve tam tersi ve bu değişiklik de çizgi döngülerinde hayatta kalır.
Etkisi, eskiden desen alanım olan tutma alanımı silmem gerektiğidir. Ben ilk önce geçerli desen alanı temizleyerek yaparak:
s/.*//
Hangi her karakteri seçer ve onu kaldırır. Kullanamıyorum dçünkü bu benim mevcut satır döngüsü sona erecek ve bir sonraki komut tamamlanmayacaktı, bu da benim senaryoyu çöpe atacaktır.
h
Bu benzer şekilde çalışır, Hancak tutma alanının üzerine yazar , bu yüzden boş desen alanımı tutma alanımın üstüne kopyaladım, etkili bir şekilde sildim. Şimdi sadece:
b
dışarı.
Ben de böyle sedsenaryo yazıyorum .