Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Интернет » UNIX — универсальная среда программирования - Керниган Брайан Уилсон

UNIX — универсальная среда программирования - Керниган Брайан Уилсон

Читать онлайн UNIX — универсальная среда программирования - Керниган Брайан Уилсон
1 ... 47 48 49 50 51 52 53 54 55 ... 187
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

Мы могли бы определить программу ind (рассматривавшуюся в начале главы) следующим образом:

$ awk '{printf "t%sn", $0}' $*

Здесь выдается символ табуляции (t) и входная строка.

Шаблоны

Предположим, что вы хотите найти в файле /etc/passwd пользователей, не имеющих пароля. Зашифрованный пароль находится во втором поле, поэтому программа состоит из одного шаблона:

$ awk -F: '$2 == ""' /etc/passwd

Шаблон проверяет, является ли второе поле пустой строкой (операция == — это проверка на равенство).

Такой шаблон можно задать различными способами:

$2==""          Второе поле пусто

$2~/^$/         Второе поле соответствует пустой строке

$2!~/./         Второе поле не содержит ни одного символа

length($2) == 0 Длина второго поля равна нулю

Символ ~ обозначает соответствие регулярному выражению, а символ ! — отсутствие соответствия. Само регулярное выражение заключено в символы дробной черты.

Встроенная функция length программы awk вычисляет длину строки символов. Шаблону может предшествовать символ ! для отрицания его, например,

!($2=="")

Операция ! подобна такой же операции в языке Си, но в редакторе sed эта операция следует за шаблоном.

Наиболее типичное использование шаблонов в программе awk сводится к задачам простой проверки данных. Большинство из них немногим сложнее, чем поиск строк, не удовлетворяющих какому-то критерию; если нет выходного потока, то считается, что данные удовлетворяют соответствующему критерию (по принципу "отсутствие новостей — хорошая новость"). Например, в следующем шаблоне проверяется с помощью операции %, вычисляющей остаток от деления, четно или не четно число полей в каждой входной строке:

$ NF % 2 != 0 # напечатать, если нечетное число полей

Другой шаблон выдает исключительно длинные строки, используя встроенную функцию length:

length ($0) >72 # напечатать, если слишком длинная строка

В программе awk используется то же соглашение о комментарии, что и в интерпретаторе: символ # отмечает начало комментария.

Можно сделать выходной поток более информативным, снабдив его предупреждающим сообщением и частью слишком длинной строки, используя для этого встроенную функцию substr:

length($0) > 72 {print "Строка", NR, "длинная" : substr($0, 1, 60)}

Функция substr(s, m, n) выделяет подстроку из строки s, начинающуюся с символа с номером m и длиной в n символов. (Символы в строке нумеруются с 1.) Если n отсутствует, то берется подстрока от m до конца строки. Эту функцию можно использовать для выделения полей с фиксированным положением, например выделить время в часах и минутах из результата выполнения команды date:

$ date

Thu Sep 29 12:17:01 EDT 1983

$ date | awk '{print substr($4, 1, 5) }'

12:17

$

Упражнение 4.7

Сколько различных программ awk вы можете составить для переписи входного потока в выходной, как это делает команда cat? Какая из них самая короткая?

Шаблоны BEGIN и END

Программа awk имеет два специальных шаблона BEGIN и END. Действия, соответствующие BEGIN, выполняются прежде, чем читается первая входная строка; можно использовать этот шаблон для инициации переменных, печати заголовков или для установки символа разделителя полей, присваивая его переменной FS.

$ awk 'BEGIN { FS = ":" }

> $2 == "" ' /etc/paswd

$ Результата нет: все работают с паролями

Действия, указанные в шаблоне END, выполняются после обработки последней входной строки:

$ awk 'END {print NR}'...

Здесь печатается число строк входного потока.

Арифметика и переменные

До сих пор в примерах выполнялись только простые операции с текстом. Достоинством программы awk является ее возможность попутно проводить вычисления над входными данными: что-нибудь подсчитать, вычислить суммы и средние значения и т.п. Типичный пример таких вычислений — подсчет суммы столбца чисел. Так, следующая команда складывает все числа первого столбца

{s=s+$1}

END {print s}

Поскольку число значений доступно с помощью переменной NR, изменив последнюю строку на

END {print s, s/NR}

мы получим и сумму, и среднее значение.

Этот пример показывает, как используются переменные в awk. Переменная s не является встроенной, она определяется самим фактом использования. По умолчанию переменные инициируются нулем, так что, как правило, не нужно беспокоиться об их инициации.

В программе awk есть такие же сокращенные формы арифметических операторов, как и в языке Си, поэтому естественная запись примера имела бы вид:

{s+=$1}

END {print}

Запись s+=$1 равноценна записи s=s+$1, но более компактна. Можно обобщить пример по подсчету входных строк:

    { nc+=length($0) +1 # число символов, +1 для n

     nw += NF           # число слов

    }

END {print NR, nw, nc }

Здесь подсчитывается число строк, слов и символов входного потока, т.е. выполняются те же действия, что и по команде wc (хотя она и не разбивает общую сумму по файлам).

1 ... 47 48 49 50 51 52 53 54 55 ... 187
Перейти на страницу:
Открыть боковую панель
Комментарии
Jonna
Jonna 02.01.2025 - 01:03
Страстно🔥 очень страстно
Ксения
Ксения 20.12.2024 - 00:16
Через чур правильный герой. Поэтому и остался один
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее
Мприна
Мприна 08.12.2024 - 01:05
Эх, а где же продолжение?