У меня есть следующий файл данных:
variable "ARM_CLIENT_ID" {
description = "Client ID for Service Principal"
}
variable "ARM_CLIENT_SECRET" {
description = "Client Secret for Service Principal"
}
# [.....loads of code]
variable "logging_settings" {
description = "Logging settings from TFVARs"
}
variable "azure_firewall_nat_rule_collections" {
default = {}
}
variable "azure_firewall_network_rule_collections" {
default = {}
}
variable "azure_firewall_application_rule_collections" {
default = {}
}
variable "build_route_tables" {
description = "List of Route Table keys that need direct internet prior to Egress FW build"
default = [
"shared_services",
"sub_to_afw"
]
}
Есть 2 вещи, которые я хочу сделать:
default
Я знаю, что могу напечатать имена переменных так: awk '{ gsub("\"", "") }; (/variable/ && $2 !~ /^ARM_/) { print $2}'
Я знаю, что могу распечатать блоки кода с помощью: awk '/variable/,/^}/'
, что приводит к:
# [.....loads of code output before this]
variable "logging_settings" {
description = "Logging settings from TFVARs"
}
variable "azure_firewall_nat_rule_collections" {
default = {}
}
variable "azure_firewall_network_rule_collections" {
default = {}
}
variable "azure_firewall_application_rule_collections" {
default = {}
}
variable "build_route_tables" {
description = "List of Route Table keys that need direct internet prior to Egress FW build"
default = [
"shared_services",
"sub_to_afw"
]
}
Однако я не могу понять, как печатать блоки кода, «если» они не содержат default
. Я знаю, что мне нужно будет использовать оператор if
и, возможно, некоторые переменные, но я не уверен, как это сделать.
Этот блок кода НЕ должен появляться в выводе, для которого я беру имя переменной:
variable "build_route_tables" {
description = "List of Route Table keys that need direct internet prior to Egress FW build"
default = [
"shared_services",
"sub_to_afw"
]
}
Конечный вывод НЕ должен содержать те, которые имели default
:
# [.....loads of code output before this]
expressroute_settings
firewall_settings
global_settings
peering_settings
vnet_transit_object
vnet_shared_services_object
route_tables
logging_settings
Предпочтительно, чтобы это была одна команда или файл AWK, без конвейера. У меня есть применения для этого, которые предпочитают отсутствие трубопровода.
Обновлено: обновить идеальные результаты (пропущены некоторые примеры с default
)
Условие !/regexp/
будет истинным, если запись не соответствует регулярному выражению.
@Бармар; Хорошо, как я могу использовать это, чтобы удалить блок, который мне не нужен?
Если вы напечатаете только те блоки, которые удовлетворяют этому условию, вы исключите остальные блоки.
пожалуйста, обновите ожидаемый результат, чтобы он соответствовал образцу ввода (например, expressroute_settings
не находится в образце ввода, но находится в ожидаемом выводе... ??
Нет @markp-fuso, это не так, но, как вы можете видеть в верхней части этого списка, я сделал комментарий, что он включает в себя много вывода кода перед ним. в основном, я обрезал кучу бесполезного текста
@Бармар; именно это я и спрашиваю. Как мне напечатать только те блоки, которые НЕ включают в себя default
? Не имею представления.
По умолчанию ничего не печатается. Поэтому, если вы используете !/default =/
в качестве условия, он будет печатать только эти блоки.
@Бармар; не могли бы вы написать команду/формулу, чтобы я мог полностью понять, как вы хотите, чтобы это было
Используя GNU awk:
awk -v RS = "}" '/variable/ && !/default/ && !/ARN/ { var=gensub(/(^.*variable ")(.*)(".*{.*)/,"\\2",$0);print var }' file
Установите разделитель записей на «}», а затем проверьте записи, которые содержат «переменная», не содержат значения по умолчанию и не содержат «ARM». Используйте gensub, чтобы разделить строку на три части на основе регулярных выражений и установить переменную var во вторую часть. Распечатайте переменную var.
Выход:
logging_settings
Последние 3 строки не должны быть в выводе, так как у них есть default
.
Я не думаю, что ему нужны записи ARM, так что это просто logging_settings
$ awk -v RS= '!/default =/{gsub(/"/,"",$2); print $2}' file
ARM_CLIENT_ID
ARM_CLIENT_SECRET
[.....loads
logging_settings
конечно, вывод не соответствует вашему, поскольку он несовместим с входными данными.
Предположения и сборник заметок из вопроса и комментариев ОП:
}
) в первом столбце новой строкиvariable
имена (без двойных кавычек)variable
, если тело определения переменной содержит строку default
variable
, если оно начинается со строки ARM_
Одно (несколько подробное) awk
решение:
ПРИМЕЧАНИЕ. Я скопировал входные данные образца в свой локальный файл variables.dat
awk -F'"' ' # use double quotes as the input field separator
/^variable / && $2 !~ "^ARM_" { varname = $2 # if line starts with "^variable ", and field #2 is not like "^ARM_", save field #2 for later display
printme = 1 # enable our print flag
}
/variable/,/^}/ { if ( $0 ~ "default" ) # within the range of a variable definition, if we find the string "default" ...
printme = 0 # disable the print flag
next # skip to next line
}
printme { print varname # if the print flag is enabled then print the variable name and then ...
printme = 0 # disable the print flag
}
' variables.dat
Это генерирует:
logging_settings
забыл сказать "спасибо" прошлой ночью, это очень помогло и дало мне больше информации о функциональности awk
Другой вариант awk
с использованием переменной skip
для управления индексом массива, содержащим имена переменных:
awk '
/^[[:blank:]]*#/ { next }
$1= = "variable" { gsub(/["]/,"",$2); vars[skip?n:++n]=$2; skip=0 }
$1= = "default" { skip=1 }
END { if (skip) n--; for(i=1; i<=n; i++) print vars[i] }
' code
Первое правило просто пропускает строки комментариев. Если вы хотите пропустить "ARM_"
переменные, вы можете добавить тест на $2
.
Пример использования/вывода
В вашем примере кода в code
все переменные без default
:
$ awk '
> /^[[:blank:]]*#/ { next }
> $1= = "variable" { gsub(/["]/,"",$2); vars[skip?n:++n]=$2; skip=0 }
> $1= = "default" { skip=1 }
> END { if (skip) n--; for(i=1; i<=n; i++) print vars[i] }
> ' code
ARM_CLIENT_ID
ARM_CLIENT_SECRET
logging_settings
Вот еще одно, возможно, более короткое решение.
$ awk -F'"' '/^variable/&&$2!~/^ARM_/{v=$2} /default =/{v=0} /}/&&v{print v; v=0}' file
logging_settings
Почему
azure_firewall_application_rule_collections
в выводе? Блок кода имеетdefault = {}