Поведение различных версий AWK при использовании шаблона регулярных выражений
Фон:
Недавно я попытался собрать libopencm3-examples на Ubuntu 14.04 и столкнулся с ошибкой сборки (в то время как для Ubuntu 16.04.1 LTS все работает нормально). Я начал копать, чтобы найти причину. Как я обнаружил, libopencm3 использует специальный генератор сценариев компоновщика:
увидеть libopencm3-examples/libopencm3/ld/README
Цель этого инструмента - передать определенные определения целевого микроконтроллера в шаблон сценария компоновщика. Поэтому он использует препроцессор в шаблонном скрипте и передает целевые параметры, например, так:
-D_FPU=hard-fpv5-sp-d16 -D_ROM_OFF=0x08000000 -D_RAM_OFF=0x20000000
Для получения этих параметров используется скрипт awk.
./libopencm3/scripts/genlink.awk
для генерации ключей -D_XXX этот скрипт работает в базе данных устройства ./libopencm3/ld/devices.data
вот так:
awk -v PAT="$(DEVICE)" -v MODE="DEFS" -f $(OPENCM3_DIR)/scripts/genlink.awk $(OPENCM3_DIR)/ld/devices.data
Вопрос:
Часть скрипта awk, извлекающая определяемую информацию из базы данных, выглядит следующим образом:
...
for (i = 3; i <= NF; i = i + 1) {
...
else if ($i ~ /[[:upper:]]*=/) {
if ("DEFS" == MODE)
printf "-D_%s ",$i;
}
}
строка в базе данных, обработанная скриптом:
stm32f3[01]3?c* stm32f3ccm ROM=256K RAM=40K CCM=8K
Что меня смущает, так это то, что предложенный шаблон (/[[:upper:]]*=/
) должен соответствовать [ROM]=256K, например, но не ROM=256K (да?). Во всяком случае, как я уже упоминал /[[:upper:]]*=/
работает для Ubuntu 16.04 (GNU Awk 4.1.3) (почему?), а для 14.04 мне нужно было изменить /[[:upper:]]*=/
-> /[:upper:]*=/
заставить его работать (это ошибка или что?). Я что-то пропустил?
1 ответ
Нет, символ квадратной скобки является особенным в регулярном выражении. Если вы хотите соответствовать буквально, используйте \[
, Выражение [:upper:]
внутри квадратных скобок относится к классу символов, состоящему из символов верхнего регистра. Я предполагаю, что вы хотите
/[][:upper:][]+=/
сформировать выражение в скобках, состоящее из литеральной закрывающей квадратной скобки, заглавных символов и буквальной открывающей квадратной скобки. Обратите также внимание на переключение на +
вместо *
чтобы предотвратить совпадение на одиночном знаке равенства (*
означает ноль или более, поэтому при нулевом повторении он будет совпадать с любым знаком равенства).
Возможно, ваш Awk вообще не поддерживает классы символов POSIX. Затем вы можете заменить [:upper:]
с A-Z
хотя тогда он не будет соответствовать чувствительности локали.