#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 l
ook ile yazdırabilirsiniz . Daha sonra \n
karakterlere hitap edebilirsiniz .
sed l <file
Her satırın çağrıldığı sed
aşamada işlediğini gösterecektir l
.
Sadece bunu test ettik ve daha bir ihtiyaç Yani \backslash
sonra ,comma
ilk satırda, ama aksi çalışıyor gibidir. Burada bir _sed_function
cevap 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 p
bir için l
biz 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<<\SCRIPT
sadece 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, l
iç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 l
ve 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 l
meşeyi tekrar kaldırıyorum H
ve 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>$
H
eski 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 x
kez 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, H
ancak 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 sed
senaryo yazıyorum .