Hak kazanırsanız kelimeyi anlamında 1 veya daha fazla boş olmayan herhangi bir karakter dizisiyle ardından Cevap evet kesinlikle olduğunu ve çok sade bir şekilde de yapılır. Bunun nedeni, [[:blank:]]*
ve [^[:blank:]]*
boolean tamamlayıcılarıdır ve - bir dizedeki tüm karakterlerin eksiksiz olması şartıyla - [[:blank:]]*
U [^[:blank:]]*
olası tüm dizeleri de aynı şekilde tanımlayabilir .*
.
Bir dize içinde eksik bir karakter veya başka bir şekilde geçersiz bayt dizisi varsa, dizeyi doğru bir şekilde kuyruktan başa doğru tanımlayamazlar - bazen bir dizeyi yanlış kodlamada yorumlarken ortaya çıkabilir. Herhangi bir dizede bayt başına tam bir karakter sağlamak için, C yerel ayarı aşağıdaki gibi zorlanabilir:
LC_ALL=C sed ...
... dizeyi baştan sona kuyruk gibi her şey dahil bir desenle tanımlayan sorunları önler .*
veya([ ]*[^ ]*)*
Tamamen tamamlayıcı bir desen, desende herhangi bir kopma olmadan mümkün olan en son meydana gelmek için herhangi bir ipin uzunluğunu soldan sağa gerektiği kadar tekrarlayabilir. Bu, kesinlikle, normal bir dildir.
BRE:
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
ERE:
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
Bu sürümlerin her ikisi de hala boş satırlar basacaktır ve bunun nedeni Kleene *
yıldızının bir desenin sıfır veya daha fazla örneğiyle eşleşmesidir. Önce sıfır veya daha fazla boş olmayan karakterle, ardından sıfır veya daha fazla boş karakterle eşleşir, ardından gruplanmış dizenin tümüyle eşleşinceye kadar sıfır veya daha fazla eşleşmesi eşleşir.
Tüm bunlarla eşleştikten sonra sihir, yedekte gerçekleşir - gruplar tarafından döndürülen referanslar \1
ve \2
her birinin son oluşumlarıdır. Bu nedenle, değiştirme yapıldığında tüm dize, sıfır veya daha fazla boş karakter olmayan bir satırda veya alt grupta yalnızca son tekrarlama ile değiştirilir \2
.
Tabii ki bu, olası boş bir dize - hatta boş bir dizgi - için çalışır, bu da her iki formun da yalnızca boş karakterler içeren veya hiç boş olmayan satırlar için yeni satır karakterleri yazdıracağı anlamına gelir. Bunu yapmak için yapabileceğiniz birkaç şey var, ama önce karakter sınıfını yazmayı biraz daha kolaylaştıralım:
b='[:blank:]'
Şimdi, yalnızca bir satır boş olmayan bir veya daha fazla karakter içeriyorsa yazdırmak için şunları yapabilirsiniz:
BRE:
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
ERE:
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
- BRE durumu - değiştirme her zaman gerçekleştirilir ve yalnızca en az bir karakter kalan desen boşlukları yazdırılır.
- ERE durumu - yerine koyma, yalnızca en az bir boş karakter içermeyen bir desen alanında denenir.
Her iki form da sözdizimi doğru olduğu sürece her iki yöntemle de çalışır.
-n
Desen alanı anahtarı devre dışı bırakır baskı otomatik ve p
karşı bayrak s///
ubstitution veya /
adres /
komutları sonuçları yalnızca başarılı yazdırır.
Aynı mantık, aşağıdaki gibi herhangi bir {num}
olayı elde etmek için de uygulanabilir :
BRE:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
ERE:
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... num
her iki normal ifadede de yalnızca {num}
boş olmayan karakterlerden oluşan bir dizinin yalnızca belirtilen örneğini basmak için bir sayıyla değiştirilebilir . Burada, dizenin önde gelen alanı için sayının eğri olmamasını sağlamak için biraz farklı bir form kullanılır.
-E
ERE anahtarının sed
, henüz POSIX standart sözdizimi olmasa da, hem BSD hem de GNU sürümlerinde desteklendiğini unutmayın .
sed
mı?