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'
Bu parça sed
sadece is
bir satırdan diğerine olayların bir çetelesini taşır . is
Satır başına attığınız kadar çok es'yi güvenilir bir şekilde ele almalıdır ve eski satırları arabelleklemesine gerek yoktur - is
karşılaştığı her şey için başka bir kelimenin parçası olmayan tek bir yeni satır karakteri tutar .
Sonuç olarak, bir dosyada yalnızca üçüncü olayı değiştirecek ve satır başına sayı taşıyacaktır. Yani bir dosya şöyle görünürse:
1. is is isis
2. is does
... yazdıracak ...
1. is is isis
2. us does
Her satırın başına ve kuyruğuna boşluk bırakarak ilk önce kenar kasaları ele alır. Bu, kelime sınırlarının anlaşılmasını biraz daha kolaylaştırır.
Daha sonra , sıfırdan veya bir noktalama karakterinden hemen önce bir boşluk izleyen is
bir \n
ewline ekleyerek geçerli es arar is
. Başka bir geçiş yapar ve \n
hemen önünde boşluk olmayan bir karakter olan tüm ewline'ları kaldırır . Geride kalan bu işaretçiler eşleşir is.
, is
ancak eşleşmez this
veya ?is
.
Daha sonra her bir işaretçiyi dizenin kuyruğuna toplar - \ni
bir çizgideki her eşleşme \n
için dizenin kuyruğuna bir ewline ekler ve onunla i
veya ile değiştirilir u
. Eğer \n
dizginin kuyruğunda toplanmış bir satırda 3 ewline varsa u - else i'yi kullanır. Au ilk kullanıldığında da sonuncusudur - değiştirme, aşağı doğru kaybolan sonsuz bir döngü başlatır get line, print line, get line, print line,
.
Her deneme döngüsü döngüsünün sonunda, eklenen boşlukları temizler, desen alanında yalnızca ilk oluşan satır sonuna kadar yazdırır ve tekrar gider.
l
Döngünün başına bir ook komutu ekleyeceğim :
l; s/\ni(.* )\n{9}/u\1/...
... ve bu girdiyle çalışırken neler yaptığına bir göz atın:
hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged is.
... işte burada yaptığı şey:
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
Her satırda daha fazla es ile daha mantıklı :
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'
)
Bu hemen hemen aynı şey ama POSIX BRE ve ilkel argüman yönetimiyle yazılmış.
printf 'is is. is? this is%.0s\n' {1..4} | nthword is us 12
... alır ...
is is. is? this is
is is. is? this is
is is. is? this us
is is. is? this is
... ve etkinleştirirsem ${dbg}
:
printf 'is is. is? this is%.0s\n' {1..4} |
dbg=1 nthword is us 12
... yinelemesini izleyebiliriz ...
\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