Основи

Основи

Навчальна вправа

Вступ

Основи

Мову ми називатимемо 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, наведемо поширену ідіому AWK.
      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, підтримували його в актуальному й захищеному стані та дбали про те, щоб доступ до системи мали лише авторизовані користувачі.

Тепер наша черга побути системним адміністратором, як Алекс.

Note

Ось додатковий синтаксис AWK, який знадобиться, щоб розвʼязати цю вправу.

  • Булеві оператори (англ. Boolean) схожі на ті, що є в інших мовах:

    операція приклад
    Логічне і expr1 && expr2
    Логічне або expr1 || expr2
    Логічне заперечення ! expr
  • Виклик функції має знайомий синтаксис:

    function greet(name) {
        print "Hello", name
    }
    BEGIN {
        greet("Mary")   # prints "Hello Mary"
    }
    

1. Вивести список імен користувачів

Напишіть програму awk, яка виводить перше поле, відокремлене двокрапкою, для кожного рядка у файлі passwd.

2. Вивести номери рядків

Напишіть команду awk, яка виводить номер рядка кожного запису у вхідному файлі. Виводьте лише номер рядка, без жодної іншої інформації.

3. Вивести записи з недійсними домашніми каталогами.

У Кіберпросторі «дійсний» домашній каталог починається з /home або /root. Виведіть записи з вхідного файлу, у яких домашні каталоги недійсні.

4. Вивести дійсних користувачів, які використовують bash

Виведіть записи, у яких домашній каталог дійсний, і командна оболонка входу - bash.


Джерело

Розмова з ChatGPT
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
AWK Exercism

Час розпочати Основи?

Зареєструйтеся на Exercism, щоб вивчати й опановувати AWK, а також 3 концепції92 вправи та справжнє наставництво від людей, і все це безкоштовно.