да, это ожидаемое поведение, поскольку BEGIN
раздел в awk
выполняется перед чтением файла Input_file, поэтому НЕ ДОЛЖНО передавать имя файла Input_file, следовательно, ваш первый awk
работает.Но в вашем другом awk
вы ЗАКРЫЛИ раздел BEGIN
, а затем открыли ГЛАВНЫЙ БЛОК на {...}
, поэтому для его выполнения требуется Input_file.
См. Также со страницы man awk
:
BEGIN and END are two special kinds of patterns which are not tested against the input. The action parts of all BEGIN patterns are
объединены, как если бы все операторы были записаны в одном блоке BEGIN.Они выполняются до того, как любой из входных данных будет прочитан.Точно так же все блоки END объединяются и выполняются, когда исчерпаны все входные данные (или когда выполняется оператор выхода).Шаблоны BEGIN и END нельзя сочетать с другими шаблонами в выражениях шаблонов.На начальных и конечных образцах не должно быть пропущенных частей действия.
Ваш 1-й awk
:
awk 'BEGIN{ color["one"]="red"; color["two"]="orange";print color["one"] }'
После BEGIN
в разделе НЕТ утверждений, поэтому он работает ожидаемым образом и выдает red
в качестве вывода.
Ваш второй awk
: Давайте разделим его на 2 части
1-я часть (для понимания):
awk 'BEGIN{ color["one"]="red"; color["two"]="orange"}
2-я часть (для понимания):
{print color["one"] }'
Итак, 1-я часть - это секция BEGIN
, а 2-я часть - main block
, которая ожидает, что файл Input_file будет передан программе awk
.
Ответ, почему инициализируется переменнаяили массивы в секции BEGIN
: На ваш вопрос, почему нужно инициировать переменные или массив в блоке BEGIN
, поскольку секция BEGIN
выполняетсяперед основным блоком, когда читается Input_file, поэтому хорошо, чтобы там была вся инициализация переменных и массивов, чтобы избежать их повторного запуска или инициализации с условием (который будет проверяться каждый раз, когда читается каждая строка).Поэтому ИМХО рекомендуется инициализировать их в разделе BEGIN
.