Awk komutuyla BEGIN ve END


13

Awk kılavuzuna göre, BEGIN ve END girişleri eşleştirmek için değil, awk betiğine başlatma ve temizleme bilgileri sağlamak için kullanılır. Aşağıda verilen örnek verilmiştir:

ls -l | \
awk 'BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }'
Files found:
amd.conf
antivir.conf
xcdroast.conf
xinetd.conf

İlk olarak çıktı için bir dize yazdırılır. Daha sonra girdiyi, desen eşleşmesi için kontrol eder; burada giriş, a veya x, ardından herhangi bir karakterle veya birkaç kez ve .conf ile başlar. Herhangi bir eşleşme için 9. sütun yazdırılır.

Kullanmaya zorlandığımız gerçeği burada başlıyor, yani awk sadece bir BEGIN veya END içeren en fazla bir yazdırma işlevini kullanabilir mi? Değilse, neden başlangıçta BEGIN anahtar kelimesi olmadan baskı işlevini kullanamıyoruz? BEGIN gereksiz görünüyor.


Komutu BEGIN olmadan çalıştırmak, sorunun gereksiz olmadığını ve farklı bir sonuç alacağınızı göstererek sorunuza cevap verecektir.
msb

Yanıtlar:


11

BEGINGereksiz değildir. Eğer belirtmezseniz BEGINsonra printgirdinin her satır için idam edilecektir.

Kılavuzdan alıntı :

BEGINİlk giriş kaydı okunmadan önce bir kural yalnızca bir kez yürütülür. Benzer şekilde, ENDtüm girdi okunduktan sonra bir kural yalnızca bir kez yürütülür.

$ seq 5 | awk 'BEGIN{print "Hello"}/4/{print}'   # Hello printed once
Hello
4
$ seq 5 | awk '{print "Hello"}/4/{print}'        # Hello printed for each line of input
Hello
Hello
Hello
Hello
4
Hello
$

7

awkvücutta verilen ifadeler için her girdi satırını işler BEGINve ENDengeller. BEGINVe ENDblokları durumunda, awkgirdilerin işlenmesi başlamadan önce ve girdilerin işlenmesi tamamlandıktan sonra ifadeleri yalnızca bir kez işleyecektir. BEGINBlok olmadan, yalnızca üstbilgiler gibi bir kerelik bilgileri yazdıramazsınız, aynı zamanda gövdenin gerektirdiği bazı değişkenleri verimli bir şekilde başlatamazsınız. Ayrıca, FYI, bir awkprogram birden fazla BEGINve ENDblok olabilir.


2

awkher bloğu sadece desen eşleşmeden önce çalıştırır. Boş desen (sadece engelle) her satırla eşleşir. BEGINve ENDdosyanın başlangıcına ve sonuna uyan özel kalıplardır ( yatay yönde ^ve anlamına benzer $).

Dosyayı okumadan önce bir şeyin yürütülmesini istiyorsanız kullanın BEGIN. Örneğin, sayaçların başlatılması vb. ENDsonuçları toplayabilir.


0

Pedagojik netlik için basitleştirildiğini düşündüğüm örnekte, bunun gereksiz olduğu konusunda haklısınız. Aynı sonuçları kullanmadan da alabilirsiniz BEGIN.

1 == NR            { print "Files found:\n" }
/\<[a|x].*\.conf$/ { print $9               }

print ifadesi yalnızca ilk girdi satırıyla sınırlı olduğundan aynı sonuçları üretir.

Olduğu söyleniyor, BEGINve ENDbloklar inanılmaz derecede güçlü araçlardır. Diğer çözümlerin de belirttiği gibi, BEGINyalnızca bir kez gerçekleştirilmesi gereken değişkenleri veya diğer rutinleri başlatmak için bloğu kullanabilirsiniz, ancak işlenecek dosya olmadığında Awk komutlarını çalıştırmak için de kullanılabilir. Basit bir örnek:

BEGIN { print sqrt(12/4) }

Burada herhangi bir girdi işlemeden Awk programlamanın daha ciddi bir örneğini görebilirsiniz .

Benzer şekilde, ENDblok hesaplamaları yapmak ve tüm girdileri özetlemek için son derece yararlıdır. Bu, tüm verilerden önce okunmadan (genellikle) yapılamaz. Girdileri özetlemenin basit bir örneğini burada bulabilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.