p='[:punct:]' s='[:space:]'
sed -Ee'1!{/\n/!b' -e\} \
-e's/(\n*)(.*)/ \2 \1/' \
-e"s/is[$p]?[$s]/\n&/g" \
-e"s/([^$s])\n/\1/g;1G" \
-e:c -e"s/\ni(.* )\n{3}/u\1/" \
-e"/\n$/!s/\n//g;/\ni/G" \
-e's//i/;//tc' \
-e's/^ (.*) /\1/;P;$d;N;D'
บิตเหล่าsed
นั้นมีจำนวนis
ครั้งเกิดขึ้นจากหนึ่งบรรทัดไปยังอีกบรรทัดหนึ่ง มันควรจะจัดการได้อย่างน่าเชื่อถือis
ต่อ es มากที่สุดเท่าที่คุณโยนมันและมันไม่จำเป็นต้องบัฟเฟอร์บรรทัดเก่าในขณะที่มันทำ - มันเพียงแค่รักษาอักขระบรรทัดใหม่เดียวสำหรับทุกis
ที่พบซึ่งไม่ได้เป็นส่วนหนึ่งของคำอื่น
ผลที่สุดคือมันจะแก้ไขเพียงครั้งที่สามที่เกิดขึ้นในไฟล์ - และมันจะดำเนินการนับต่อบรรทัด ดังนั้นหากไฟล์มีลักษณะดังนี้:
1. is is isis
2. is does
... มันจะพิมพ์ ...
1. is is isis
2. us does
มันจัดการกับกรณีขอบโดยการใส่ช่องว่างที่หัวและส่วนท้ายของทุกบรรทัด ทำให้ขอบเขตของคำง่ายขึ้นเล็กน้อยในการตรวจสอบให้แน่ใจ
ถัดไปจะค้นหาis
es ที่ถูกต้องโดยการแทรก\n
ewline ก่อนที่เหตุการณ์ทั้งหมดนั้นจะเกิดขึ้นis
ทันทีนำหน้าศูนย์หรืออักขระเครื่องหมายวรรคตอนหนึ่งอันตามด้วยช่องว่างในทันที มันจะส่งผ่านอีกครั้งและลบ\n
ewlines ทั้งหมดที่นำหน้าด้วยอักขระที่ไม่ใช่ช่องว่างทันที เครื่องหมายนี้ทิ้งไว้ข้างหลังจะตรงis.
และis
แต่ไม่this
หรือ?is
หรือ
รวบรวมต่อไปแต่ละเครื่องหมายถึงหางของสตริง - สำหรับทุก\ni
การแข่งขันบนเส้นมันผนวก\n
ewline ถึงหางของสตริงและแทนที่มันด้วยกับทั้งหรือi
u
หากมี 3 \n
ewlines ในแถวที่รวมกันที่ส่วนท้ายของสตริงจะใช้ u - else i ครั้งแรกที่ใช้ au เป็นครั้งสุดท้าย - การแทนที่จะกำหนดลูปที่ไม่มีที่สิ้นสุดซึ่งจะลดลงget line, print line, get line, print line,
เรื่อย ๆ
ในตอนท้ายของแต่ละรอบลองลูปมันจะล้างช่องว่างที่แทรกไว้พิมพ์เฉพาะบรรทัดใหม่ที่เกิดขึ้นครั้งแรกในพื้นที่รูปแบบและไปอีกครั้ง
ฉันจะเพิ่มl
คำสั่ง ook ที่ส่วนหัวของห่วงเช่น:
l; s/\ni(.* )\n{9}/u\1/...
... และดูว่ามันทำงานอย่างไรกับข้อมูลนี้:
hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged is.
... ดังนั้นนี่คือสิ่งที่ทำ:
hai this \nis linux. \n$ #behind the scenes
hai this is linux. #actually printed
hai this \nis unix. \n\n$ #it builds the marker string
hai this is unix.
\n\n\n$ #only for lines matching the
\n\n\n$ #pattern - and not otherwise.
hai this \nis mac. \n\n\n$ #here's the match - 3 ises so far in file.
hai this us mac. #printed
hai this is unchanged is. #no look here - this line is never evaled
มันสมเหตุสมผลมากกว่าบางทีอาจมีis
es ต่อบรรทัดมากขึ้น:
nthword()( p='[:punct:]' s='[:space:]'
sed -e '1!{/\n/!b' -e\} \
-e 's/\(\n*\)\(.*\)/ \2 \1/' \
-e "s/$1[$p]\{0,1\}[$s]/\n&/g" \
-e "s/\([^$s]\)\n/\1/g;1G;:c" \
-e "${dbg+l;}s/\n$1\(.* \)\n\{$3\}/$2\1/" \
-e '/\n$/!s/\n//g;/\n'"$1/G" \
-e "s//$1/;//tc" -e 's/^ \(.*\) /\1/' \
-e 'P;$d;N;D'
)
นั่นคือสิ่งเดียวกัน แต่เขียน w / POSIX BRE และการจัดการอาร์กิวเมนต์เบื้องต้น
printf 'is is. is? this is%.0s\n' {1..4} | nthword is us 12
... ได้รับ ...
is is. is? this is
is is. is? this is
is is. is? this us
is is. is? this is
... และถ้าฉันเปิดใช้งาน${dbg}
:
printf 'is is. is? this is%.0s\n' {1..4} |
dbg=1 nthword is us 12
... เราสามารถดูมันซ้ำ ...
\nis \nis. \nis? this \nis \n$
is \nis. \nis? this \nis \n\n$
is is. \nis? this \nis \n\n\n$
is is. is? this \nis \n\n\n\n$
is is. is? this is
\nis \nis. \nis? this \nis \n\n\n\n\n$
is \nis. \nis? this \nis \n\n\n\n\n\n$
is is. \nis? this \nis \n\n\n\n\n\n\n$
is is. is? this \nis \n\n\n\n\n\n\n\n$
is is. is? this is
\nis \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n$
is \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n\n$
is is. \nis? this \nis \n\n\n\n\n\n\n\n\n\n\n$
is is. is? this \nis \n\n\n\n\n\n\n\n\n\n\n\n$
is is. is? this us
is is. is? this is