BEGIN і END з командою awk


13

Відповідно до посібника awk, BEGIN і END не використовуються для відповідності вводу, а для надання інформації про запуск та очищення сценарію awk. Ось наведений приклад:

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

Спочатку це друкує рядок для виведення. Потім він перевіряє введення на відповідність шаблону, де вхід починається з a або x, а потім будь-який символ, один або багато разів, після якого .conf. Для будь-яких матчів друкується 9-й стовпчик.

Те, що ми змушені використовувати тут, починається тут, чи це означає, що awk може використовувати лише максимум одну функцію друку, яка містить BEGIN або END? Якщо ні, то чому ми не можемо просто використати функцію друку на початку без ключового слова ПОЧАТИ? Здається, ПОЧАТО зайве.


Просто виконання команди без BEGIN відповість на ваше запитання, показавши, що це не зайве і що ви отримаєте інший результат.
msb

Відповіді:


11

Це BEGINне зайве. Якщо ви не вказуєте, BEGINто воно printбуде виконуватися для кожного рядка введення.

Цитуючи посібник :

BEGINПравило виконується тільки один раз, перед першим входом запис читається. Так само ENDправило виконується лише один раз, після того, як буде прочитано весь вхід.

$ 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

awkобробляє кожен рядок введення для виразів, поданих у тілі, крім BEGINта ENDблоків. У випадку BEGINі ENDблоків, awkобробляти оператори буде лише один раз, перш ніж почалася обробка вводу та після того, як буде виконана обробка вводу відповідно. Без BEGINблоку ви не тільки не змогли б надрукувати одноразову інформацію, таку як заголовки, ви не змогли б ефективно ініціалізувати деякі змінні, необхідні тілу. Також FYI, awkпрограма може мати кілька BEGINі ENDблоків.


2

awkвиконує кожен блок лише тоді, коли шаблон перед ним відповідає. Порожній шаблон (просто блок) відповідає кожному рядку. BEGINі ENDце спеціальні візерунки, які відповідають початку та кінці файлу (аналогічні значенню ^та $в горизонтальному напрямку).

Якщо ви хочете щось виконати перед читанням файлу, використовуйте BEGIN. Наприклад, ініціалізація лічильників чи щось таке. ENDможе зібрати результати.


0

У наведеному прикладі, який, на мою думку, спрощений для педагогічної ясності, ви маєте рацію, що це зайве. Ви можете отримати ті самі результати, не використовуючи BEGIN.

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

дав би ті самі результати, оскільки оператор друку обмежений лише першим рядком введення.

Як сказано, BEGINі ENDблоки є неймовірно потужними інструментами. Як уже згадувалося в інших рішеннях, ви можете використовувати BEGINблок для ініціалізації змінних або інших процедур, які потрібно виконати лише один раз, але вони також можуть бути використані для запуску команд Awk, коли файлів немає для обробки. Простий приклад:

BEGIN { print sqrt(12/4) }

Ви можете побачити більш серйозний приклад програмування в Awk, не обробляючи тут жодного вводу .

Аналогічно, ENDблок є надзвичайно корисним для виконання обчислень та підбиття підсумків усіх вхідних даних. Це неможливо зробити (як правило) без попереднього читання всіх даних. Простий приклад підбиття підсумків можна знайти тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.