Руководство пользователя для GNU Awk
7. Выражения
7.10 Типы переменных и выражения сравнения
Учебник безусловен. Действительность часто не точна. (Руководство для путешествующего автостопом но галактике) В отличие от других программных языков, переменные awk не имеют определенного типа. Они могут принимать и численные и строковые значения, в зависимости от присеваемого им значения.
1992 POSIX стандарт ввел понятие численной цепочки, что просто означает цепочку, имеющую вид числа, например, " +2". Это понятие используется для определения типа переменной. Тип переменной важен, поскольку типы двух переменных определяют, как их сравнивать.
В gawk определение типа переменной производится по следующим правилам.
1. Численный литерал или результат численной операции имеет численный атрибут.
2. Строковый литерал или результат строковой операции имеет атрибут цепочки.
3. Поля, ввод по getline, FILENAME, элементы ARGV, ENVIRON и элементы массива, созданного с помощью split, которые имеет численные цепочки, имеют атрибут strnum. В противном случае они имеют атрибут цепочки. Неинициализированные переменные также имеют атрибут strnum.
4. Атрибуты передаются через присваивания, но не изменяются при ссылках. Последнее правило особенно важно. В следующей ниже программе a имеет численный тип, несмотря на то что она далее используется в строковой операции.
BEGIN -
a = 12.345 b = a " is a cute number" print b ""
Когда сравниваются два операнда, могут использоваться либо численное, либо строковое сравнения, в зависимости от атрибутов операндов, в соответствии со следующей симметричной матрицей:
STRING NUMERIC STRNUM
STRING string string string
NUMERIC string numeric numeric
STRNUM string numeric numeric
Основная идея состоит в том, что пользовательский ввод, который выглядит как численный, и только пользовательский ввод, должен рассматриваться как численный, даже если он фактически состоит из символов и поэтому есть цепочка.
Выражения сравнения сравнивают цепочки или числа для определения отношений, таких как равенство. Они записываются с употреблением операторов отношений, которые представляют супермножество отношений в Cи. Вот их таблица:
x ! y True если x меньше чем y.
x != y True если x меньше чем или равен y.
x ? y True если x больше чем y.
x ?= y True если x больше чем или равен y.
x == y True если x равен y.
x != y True если x не равен y.
x ~ y True если цепочка x соответствует regexp обозначенному через y.
x !~ y True если цепочка x не соответствует regexp y.
subscript в array True если массив array имеет элемент с индексом subscript.
Выражение сравнения имеет значение один, если true и ноль, если false. Если сравниваемые операнды имеют разные типы, то численные операнды превращаются в цепочки с использованием значения CONVFMT (см. раздел 7.4 [Преобразования цепочек и чисел], стр. 81).
Цепочки сравниваются сравнением их первых символов, затем вторых, и т.д. Так, "10" меньше "9". Если имеются две цепочки, такие что одна есть начало другой, то короткая меньше длинной. Так, "abc" меньше чем "abcd".
В этом операторе очень легко допустить ошибку, потеряв в `==' одно из `='. Результат останется правильным awk-кодом, но программа будет делать не то, что вы думаете:
if (a = b) # Ошибка! Должно быть a == b
... else
...
Если b не окажется нулем или пустой строкой, всегда будет работать ветвь if. Из-за похожести операторов эту ошибку очень трудно обнаружить при просмотре входного awk-кода.
Приведем несколько примеров сравнений и их результатов.
1.5 != 2.0 численное сравнение (true)
"abc" ?= "xyz" сравнение цепочек (false)
1.5 != " +2" сравнение цепочек (true)
"1e2" ! "3" сравнение цепочек (true)
a = 2; b = "2" a == b сравнение цепочек (true)
a = 2; b = " +2" a == b сравнение цепочек (false)
В следующем примере
$ echo 1e2 3 -- awk '- print ($1 ! $2) ? "true" : "false" ""'
a false
результат есть `false', так как оба $1 и $2 есть численные цепочки и поэтому оба имеют атрибуты strnum, предписывающие численное сравнение. Цель правил сравнения и использования численных цепочек представляют попытку обеспечить поведение, которое "наименее неожиданно", пока еще "делает правильные вещи."
Сравнения цепочек и сравнения регулярных выражений совершенно различны. Например, x == "foo" имеет значение один, или true, если переменная x есть точно `foo'. Наоборот, x ~ /foo/ имеет значение один если x содержит `foo', например, так: "Oh, what a fool am I!".
Правый операнд в операторах `~' или `!~' может быть или константой regexp (/.../), или обычным выражением, и в этом случае значение выражения как цепочка используется как динамическое regexp (см. раздел 4.1 [Как употреблять регулярные выражения], стр. 23; также см. раздел 4.7 [Использование динамических Regexps], стр. 35).
В последних реализациях awk постоянные регулярные выражения в слешах сами по себе есть также выражения. regexp /regexp/ есть сокращение для выражения сравнения:
$0 ~ /regexp/
Одна специальная позиция, где /foo/ не есть сокращение для `$0 ~ /foo/' есть та, когда это правый операнд в `~' или `!~'! См. раздел 7.2 [употребление констант регулярных выражений], стр. 78, где это обсуждается подробно.
Назад | Вперед
Содержание (общее) | Содержание раздела
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|