#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
หากคุณทำตามข้างต้นให้ข้อมูลที่คุณแสดงก่อนบรรทัดการล้างข้อมูลสุดท้ายที่นั่นคุณควรทำงานกับsed
พื้นที่รูปแบบที่มีลักษณะดังนี้:
^\n<tag1>\n<tag2>foo</tag2>\n</tag1>$
คุณสามารถพิมพ์รูปแบบพื้นที่ของคุณเมื่อใดก็ได้ที่คุณต้องการด้วยl
ook จากนั้นคุณสามารถระบุที่อยู่เป็น\n
ตัวอักษร
sed l <file
จะแสดงให้คุณเห็นแต่ละบรรทัดsed
ประมวลผลในระยะที่l
เรียกว่า
ดังนั้นฉันเพิ่งทดสอบและต้องการอีกหนึ่ง\backslash
หลังจาก,comma
ในบรรทัดแรก แต่ทำงานได้ ที่นี่ฉันใส่ไว้ใน_sed_function
เพื่อให้ฉันสามารถเรียกมันได้อย่างง่ายดายเพื่อวัตถุประสงค์ในการสาธิตตลอดคำตอบนี้: (ทำงานร่วมกับความคิดเห็นรวม แต่จะถูกลบออกที่นี่เพื่อประโยชน์ของความกะทัดรัด)
_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>
ตอนนี้เราจะเปลี่ยนp
เพื่อl
ให้เราสามารถเห็นสิ่งที่เรากำลังทำงานกับในขณะที่เราพัฒนาสคริปต์ของเราและลบการสาธิตที่ไม่ใช่ op s?
ดังนั้นบรรทัดสุดท้ายของเราsed 3<<\SCRIPT
เพียงแค่มีลักษณะ:
l;s/.*//;h;b}}
จากนั้นฉันจะเรียกใช้อีกครั้ง:
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
ตกลง! ดังนั้นฉันพูดถูก - นั่นเป็นความรู้สึกที่ดี ทีนี้เราลองสลับl
ook รอบ ๆ เพื่อดูบรรทัดที่ดึงเข้าไป แต่ลบออก เราจะลบปัจจุบันของเราl
และเพิ่มหนึ่งรายการ!{block}
เพื่อให้ดูเหมือนว่า:
!{l;s/.*//;h;b}
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
นั่นคือสิ่งที่ดูเหมือนก่อนที่เราจะล้างมันออกไป
สิ่งสุดท้ายที่ฉันต้องการแสดงให้คุณเห็นคือH
พื้นที่เก่าที่เราสร้างมันขึ้นมา มีแนวคิดหลักสองสามข้อที่ฉันหวังว่าฉันจะสามารถสาธิตได้ ดังนั้นฉันจะลบl
ook สุดท้ายอีกครั้งและแก้ไขบรรทัดแรกเพื่อเพิ่มการค้นหาในH
พื้นที่เก่าในตอนท้าย:
{ 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
พื้นที่เก่ามีชีวิตรอดรอบเส้น - จึงชื่อ ดังนั้นสิ่งที่ผู้คนมักจะเดินทางไป - โอเคสิ่งที่ฉันมักจะเดินทางไป - คือมันต้องการลบหลังจากที่คุณใช้มัน ในกรณีนี้ฉันจะx
เปลี่ยนเพียงครั้งเดียวดังนั้นพื้นที่พักกลายเป็นพื้นที่รูปแบบและในทางกลับกันและการเปลี่ยนแปลงนี้ยังมีชีวิตอยู่ในรอบบรรทัด
ผลที่ได้คือฉันต้องลบพื้นที่พักซึ่งเคยเป็นพื้นที่รูปแบบของฉัน ฉันทำสิ่งนี้โดยการล้างพื้นที่รูปแบบปัจจุบันด้วย:
s/.*//
ซึ่งเพียงเลือกตัวละครทุกตัวและลบออก ฉันไม่สามารถใช้d
เพราะสิ่งนี้จะจบรอบบรรทัดปัจจุบันของฉันและคำสั่งถัดไปจะไม่เสร็จซึ่งจะทำให้สคริปต์ของฉันค่อนข้างสวย
h
วิธีนี้ใช้ได้ในลักษณะคล้ายกันH
แต่เขียนทับพื้นที่ว่างดังนั้นฉันเพิ่งคัดลอกพื้นที่รูปแบบเปล่าของฉันไปไว้ด้านบนของพื้นที่พักของฉันเพื่อลบอย่างมีประสิทธิภาพ ตอนนี้ฉันสามารถ:
b
ออก.
และนั่นคือวิธีที่ฉันเขียนsed
สคริปต์