Мову ми називатимемо AWK, а виконувану програму, яка інтерпретує програми AWK, називатимемо awk або gawk.
Програма AWK складається з пар «шаблон-дія»
pattern1 { action1 }
pattern2 { action2 }
...
Шаблон може бути шаблоном регулярного виразу, з яким зіставляються вхідні дані. Ним також може бути будь-який вираз, який дає значення правда або неправда.
Дія - це одна або кілька команд AWK. Фігурні дужки навколо неї обовʼязкові.
Якщо результат шаблону правда, тоді відповідна дія виконується.
AWK розбирає вхідні дані як послідовність записів. Кожен запис розбивається на нуль або більше полів.
Типова поведінка така:
Шаблон можна опустити, і тоді дія виконується для кожного вхідного запису.
Дію теж можна опустити, і тоді типовою дією стає виведення поточного запису.
Є два спеціальні шаблони, які використовують досить часто.
BEGIN виконує повʼязану з ним дію, перш ніж буде прочитано будь-які вхідні дані.END виконує повʼязану з ним дію після того, як усі вхідні дані буде прочитано.На поля ми посилаємося як на $1, $2, $3 тощо.
Поточний запис - це $0.
Ось кілька інших вбудованих змінних, які часто використовують.
RS - роздільник записів у вхідних даних.
Як уже згадувалося, його типове значення - символ нового рядка.FS - роздільник полів у вхідних даних.Ці змінні часто задають у блоці дії BEGIN.
AWK встановлює ці змінні автоматично під час виконання програми.
NF зберігає кількість полів у поточному записі.
$NF.NR зберігає номер поточного запису.
NR містить загальну кількість записів, оброблених на цей момент.FNR зберігає номер поточного запису в поточному вхідному файлі.
NR == FNR {action}
Вона означає «якщо накопичений номер запису дорівнює номеру запису в поточному файлі».
Це може бути правдою лише для записів у першому вхідному файлі.AWK використовує те саме поняття істинності, що й C.
0 - неправда.Оскільки AWK - мова обробки тексту, значення істинності поширюються й на рядки тексту (англ. string).
"" - неправда.Коментарі починаються із символу # і тривають до кінця рядка.
У Unix-подібних системах /etc/passwd містить інформацію про користувачів.
Кожен користувач описаний в окремому рядку, а поля розділені двокрапками.
Щоб вивести список імен користувачів:
awk '
BEGIN { FS = ":" }
{ print $1 }
' /etc/passwd
Зауважмо, що дія {print $1} не має шаблону, тож вона виконується для кожного запису.
Якщо обмежити виведення лише користувачами, які використовують bash як оболонку входу, можна зробити так:
awk '
BEGIN { FS = ":" }
$7 == "/bin/bash" { print $1 }
' /etc/passwd
Жив-був собі гамірний град на імʼя Кіберпростір. Кіберпростір був цифровим мегаполісом, де мільйони мешканців щодня входили в систему й виходили з неї. Щоб стежити за всіма цими користувачами, у Кіберпросторі був особливий файл /etc/passwd.
Файл /etc/passwd був для міста як телефонний довідник. У ньому було перелічено кожного користувача, який мав обліковий запис у системі, разом із важливою інформацією про кожного з них:
| n | поле |
|---|---|
| 1 | імʼя користувача |
| 2 | пароль («x» означає, що справжній пароль зберігається деінде, з міркувань безпеки) |
| 3 | UID, унікальний числовий ідентифікатор користувача |
| 4 | GID, унікальний числовий ідентифікатор групи (зазвичай збігається з UID) |
| 5 | інформація про користувача (зазвичай повне імʼя користувача, але може містити й інші дані) |
| 6 | домашній каталог |
| 7 | командна оболонка входу |
Поля розділені символом двокрапки. Ось типовий запис:
glennj:x:1010:1010:Glenn Jackman:/home/glennj:/usr/local/bin/fish
Файлом керувала команда системних адміністраторів, які створювали нові облікові записи, оновлювали наявні та видаляли старі. Системні адміністратори були воротарями Кіберпростору й дбали про те, щоб доступ до системи мали лише авторизовані користувачі.
Одного дня до команди приєднався новий системний адміністратор на імʼя Алекс. Алекс із захопленням узялися до роботи й швидко опанували всі тонкощі файлу /etc/passwd. Вони навчилися додавати нових користувачів до системи, оновлювати інформацію про них і видаляти старих.
Працюючи з файлом /etc/passwd, Алекс помітили дещо дивне. У деяких користувачів були дивні або незвичні домашні каталоги. У когось домашнім каталогом було вказано /dev/null, а в когось - химерні шляхи, яких не існувало.
Алекс зрозуміли, що ці користувачі - не справжні люди, а фальшиві облікові записи, які створили хакери. Хакери знайшли спосіб скористатися вразливістю в системі й створили ці фальшиві записи, щоб отримати доступ до Кіберпростору.
Алекс розуміли, що потрібно діяти. Вони використали awk, щоб проаналізувати файл /etc/passwd, і написали скрипт, який виявляв усі фальшиві записи. Далі вони разом з рештою команди видалили ці записи й залатали вразливість, яка дозволила хакерам створити їх.
Завдяки тому, що Алекс використали awk, команда змогла виявити й видалити фальшиві записи та зробити Кіберпростір безпечнішим місцем для всіх. Системні адміністратори й далі керували файлом /etc/passwd, підтримували його в актуальному й захищеному стані та дбали про те, щоб доступ до системи мали лише авторизовані користувачі.
Тепер наша черга побути системним адміністратором, як Алекс.
Ось додатковий синтаксис AWK, який знадобиться, щоб розвʼязати цю вправу.
Булеві оператори (англ. Boolean) схожі на ті, що є в інших мовах:
| операція | приклад |
|---|---|
| Логічне і | expr1 && expr2 |
| Логічне або | expr1 || expr2 |
| Логічне заперечення | ! expr |
Виклик функції має знайомий синтаксис:
function greet(name) {
print "Hello", name
}
BEGIN {
greet("Mary") # prints "Hello Mary"
}
Напишіть програму awk, яка виводить перше поле, відокремлене двокрапкою, для кожного рядка у файлі passwd.
Напишіть команду awk, яка виводить номер рядка кожного запису у вхідному файлі. Виводьте лише номер рядка, без жодної іншої інформації.
У Кіберпросторі «дійсний» домашній каталог починається з /home або /root.
Виведіть записи з вхідного файлу, у яких домашні каталоги недійсні.
Виведіть записи, у яких домашній каталог дійсний, і командна оболонка входу - bash.
Зареєструйтеся на Exercism, щоб вивчати й опановувати AWK, а також 3 концепції92 вправи та справжнє наставництво від людей, і все це безкоштовно.