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
chỉ là một phần của is
sự xuất hiện từ dòng này sang dòng tiếp theo. Nó đáng tin cậy sẽ xử lý nhiều is
es mỗi dòng khi bạn ném vào nó và nó không cần phải đệm các dòng cũ trong khi nó - nó chỉ giữ lại một ký tự dòng mới cho mỗi is
câu mà nó không phải là một phần của từ khác.
Kết quả cuối cùng là nó sẽ chỉ sửa đổi lần xuất hiện thứ ba trong một tệp - và nó sẽ mang số đếm trên mỗi dòng. Vì vậy, nếu một tập tin trông giống như:
1. is is isis
2. is does
... nó sẽ in ...
1. is is isis
2. us does
Đầu tiên, nó xử lý các trường hợp cạnh bằng cách chèn một khoảng trắng ở đầu và đuôi của mỗi dòng. Điều này làm cho ranh giới từ dễ dàng hơn một chút để xác định.
Tiếp theo, nó sẽ tìm is
es hợp lệ bằng cách chèn một \n
ewline trước tất cả các lần xuất hiện is
ngay trước 0 hoặc một ký tự dấu chấm theo sau là khoảng trắng . Nó thực hiện một lần nữa và loại bỏ tất cả các \n
ewlines ngay trước một ký tự không phải không gian. Điểm đánh dấu này để lại sẽ phù hợp is.
và is
nhưng không this
hoặc ?is
.
Nó tiếp theo tập hợp mỗi điểm đánh dấu vào đuôi của chuỗi - cho mỗi \ni
trận đấu trên một dòng, nó sẽ thêm một \n
ewline vào đuôi của chuỗi và thay thế nó bằng một i
hoặc u
. Nếu có 3 \n
ewlines liên tiếp được tập hợp ở đuôi chuỗi thì nó sử dụng u - khác là i. Lần đầu tiên au được sử dụng cũng là lần cuối cùng - sự thay thế đặt ra một vòng lặp vô hạn, sôi sục lên get line, print line, get line, print line,
và cứ thế.
Vào cuối mỗi chu kỳ vòng thử, nó sẽ dọn sạch các khoảng trắng được chèn, chỉ in đến dòng mới xuất hiện đầu tiên trong không gian mẫu và đi lại.
Tôi sẽ thêm một l
lệnh ook ở đầu vòng lặp như:
l; s/\ni(.* )\n{9}/u\1/...
... và hãy xem những gì nó làm khi nó hoạt động với đầu vào này:
hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged is.
... đây là những gì nó làm:
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
Nó có ý nghĩa hơn có thể với nhiều is
es trên mỗi dòng:
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'
)
Đó thực tế là điều tương tự nhưng được viết bằng w / POSIX BRE và xử lý đối số thô sơ.
printf 'is is. is? this is%.0s\n' {1..4} | nthword is us 12
...được...
is is. is? this is
is is. is? this is
is is. is? this us
is is. is? this is
... và nếu tôi kích hoạt ${dbg}
:
printf 'is is. is? this is%.0s\n' {1..4} |
dbg=1 nthword is us 12
... chúng ta có thể xem nó lặp đi lặp lại ...
\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