Secondo il manuale di awk, BEGIN e END non sono usati per abbinare linput, ma piuttosto per fornire avvio e pulizia -up informazioni allo script awk. Ecco lesempio fornito:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Per prima cosa stampa una stringa in output. Quindi controlla linput per una corrispondenza del modello, in cui linput inizia con a o x seguito da qualsiasi carattere una o più volte seguito da .conf. Per ogni corrispondenza, viene stampata la nona colonna.
Il fatto che siamo costretti a usare inizia qui, significa che awk può usare solo al massimo una funzione di stampa che contiene un BEGIN o END? In caso contrario, perché non possiamo semplicemente utilizzare la funzione di stampa allinizio senza la parola chiave BEGIN? Sembra che BEGIN sia superfluo.
Commenti
- La semplice esecuzione del comando senza BEGIN risponderebbe alla tua domanda, dimostrando che ' non è superfluo e che otterrai un risultato diverso.
Risposta
BEGIN
non è superfluo. Se non specifichi BEGIN
, print
verrà eseguito per ogni riga di input.
Citando da il manuale :
A
BEGIN
la regola viene eseguita una sola volta, prima che il primo record di input venga letto. Allo stesso modo, una regolaEND
viene eseguita una sola volta, dopo che tutto linput è stato letto.
$ 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 $
Risposta
awk
elabora ogni riga di input per le espressioni fornite nel corpo diverse da BEGIN
e END
blocchi. Nel caso di BEGIN
e END
blocchi, awk
elaborerà le istruzioni solo una volta, prima che sia iniziata lelaborazione dellinput e dopo che lelaborazione dellinput sia stata eseguita risp ectively. Senza il blocco BEGIN
, non solo non saresti in grado di stampare informazioni una tantum come le intestazioni, ma non saresti in grado di inizializzare in modo efficiente alcune delle variabili richieste dal corpo. Inoltre, FYI, un programma awk
può avere più blocchi BEGIN
e END
.
Answer
awk
esegue ogni blocco solo quando il pattern prima di esso corrisponde. Il modello vuoto (solo blocco) corrisponde a ogni riga. BEGIN
e END
sono modelli speciali che corrispondono allinizio e alla fine del file (analogo al significato di ^
e $
in direzione orizzontale).
Se desideri eseguire qualcosa prima di leggere il file, utilizza BEGIN
. Ad esempio, inizializzazione di contatori o qualcosa del genere. END
potrebbe quindi raccogliere i risultati.
Risposta
Nellesempio fornito, il che credo sia semplificato per chiarezza pedagogica, hai ragione che è superfluo. È possibile ottenere gli stessi risultati senza utilizzare BEGIN
.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
produrrebbe gli stessi risultati poiché listruzione print è limitati solo alla prima riga di input.
Detto questo, i blocchi BEGIN
e END
sono incredibilmente potenti utensili. Come accennato in altre soluzioni, puoi utilizzare il blocco BEGIN
per inizializzare variabili o altre routine che devono essere eseguite solo una volta ma può anche essere utilizzato per eseguire comandi Awk quando non ci sono file da elaborare. Un semplice esempio:
BEGIN { print sqrt(12/4) }
Puoi vedere un esempio più serio di programmazione in Awk senza elaborare alcun input qui .
Allo stesso modo, il blocco END
è estremamente utile per eseguire calcoli e riassumere tutto linput. Questo non può essere fatto (di solito) senza prima leggere tutti i dati. Un semplice esempio di riepilogo dellinput può essere trovato qui