don, çoğu durumda daha iyi olabilir, ancak dosyanın gerçekten büyük olması ve büyük sed
bir komut dosyası (5000'in üzerinde komut satırında olabilir) ile baş edememeniz durumunda , işte düz sed
:
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
Bu girişte sürgülü pencere denilen bir örnek . Bu bir inşa ederek çalışır ileriye bakma ait tampon $B
hiç bir şey yazdırmak için çalışmadan önce -count hatları.
Ve aslında, muhtemelen daha önceki noktamı açıklığa kavuşturmalıyım: Hem bu çözüm hem de Don’lar için birincil performans sınırlayıcısı doğrudan aralıklarla ilgili olacak. Bu çözelti, daha büyük bir aralık ile yavaş olacak boyutlarda don en büyük aralığı ile yavaş olacak ise, frekans . Başka bir deyişle, giriş dosyası çok büyük olsa bile, gerçek aralık oluşumu hala çok nadirse, o zaman çözümü muhtemelen yoludur. Ancak, aralık büyüklüğü nispeten yönetilebilir ve sık sık meydana gelmesi muhtemelse, seçmeniz gereken çözüm budur.
İşte iş akışı:
- Eğer
$match
bir öncesinde desen uzayda bulunan \n
ewline, sed
yinelemeli olacak D
her elete \n
ewline olduğunu ilerlettiği o.
$match
'Nin kalıp alanını daha önce tamamen temizledim - fakat çakışmayı kolayca idare etmek için bir dönüm noktası bırakmak çok daha iyi çalışıyor gibi görünüyor.
- Aynı zamanda
s/.*\n.*\($match\)/\1/
bir seferde onu almaya çalışarak döngüyü atlatmaya çalıştım , ancak $A/$B
büyük olduğunda D
seçkin döngü önemli ölçüde daha hızlı oluyor.
- Sonra, ewline sınırlayıcısının
N
önündeki girişin ext satırını \n
çekeriz ve en son kullanılan w / w düzenli ifademize başvurarak D
bir /\n.*$match/
kez daha seçmeye çalışırız //
.
- Desen alanı eşleşirse
$match
, bunu yalnızca $match
çizginin başında yapabilir - tüm $B
efore çizgiler temizlenir.
- Böylece daha
$A
sonradan döngü başlıyoruz .
- Bu döngünün her koşmak biz deneriz
s///
için yerini tutmaz &
kendisi $A
inci \n
desen uzayda ewline karakterini ve başarılı olursa, t
bizim bütün ve - est bizi dala ayrılacak $A
tamamen üstten üzerinde senaryoyu başlatmak için komut dosyası dışarı - fter tamponunu eğer varsa bir sonraki giriş hattında.
- Eğer
t
est başarılı olmazsa b
, :t
op etiketine geri döneceğiz ve başka bir girdi satırı için tekrar elde edeceğiz - muhtemelen daha sonra $match
toplama yapılırsa döngü $A
baştan başlar.
- Biz geçmiş olsun
$match
fonksiyon döngü, o zaman çalışacağım p
Rint $
eğer bu bunu ise son satırı ve !
etmeye s///
yönelik yerini tutmaz &
kendisi $B
inci \n
desen uzayda ewline karakteri.
- Bunu da
t
tahmin edeceğiz ve eğer başarılı olursa :P
rint etiketine geçeceğiz .
- Olmazsa op'a geri dönelim
:t
ve arabelleğe başka bir giriş satırı ekleyelim.
- Biz yaparsak o kadar
:P
biz edeceğiz Rint P
sonra Rint D
ilk kadar elete \n
desen uzayda ewline ve kalanları ile üstten senaryoyu yeniden çalıştırın.
Ve bu sefer, eğer yapıyor olsaydık A=2 B=2 match=5; seq 5 | sed...
:P
Rint'deki ilk yineleme için kalıp alanı şöyle görünür:
^1\n2\n3$
Ve bu sed
, $B
efore arabelleğini böyle toplar . Ve böylece topladığı girdinin arkasındakised
çıktı- $B
sayı satırlarına yazdırır . Daha önceki örnekte verilen bu araçlar, olur rint çıkışına ve sonra elete o ve senaryonun üstüne gibi hangi görünüyor desen alanını geri göndermek:sed
P
1
D
^2\n3$
... ve betiğin üstünde N
ext giriş satırı alınır ve bir sonraki yineleme şöyle görünür:
^2\n3\n4$
Ve 5
girişin ilk oluşumunu bulduğumuzda , desen alanı aslında şöyle görünür:
^3\n4\n5$
Sonra D
seçkin döngü devreye girer ve içinden geçtiğinde şöyle görünür:
^5$
Ve ne zaman N
ext giriş hattı çekilir sed
hit EOF ve sonlandırılıyor. O zamana kadar sadece P
1. ve 2. satırları değiştirdi.
İşte bir örnek çalışma:
A=8 B=7 match='[24689]0'
seq 100 |
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
Bu yazdırır:
1
2
3
4
5
6
7
8
9
10
11
12
29
30
31
32
49
50
51
52
69
70
71
72
99
100