Используйте файл списка для редактирования главного файла через awk

Когда ваш кредитный баланс процессора пуст, хост (супервизор) просто не выделяет процессорное время (кроме очень маленького) на ваш ec2. Этого очень небольшого количества достаточно для ssh, но недостаточно для запуска голодного монстра по имени java. Поэтому экземпляр БУДЕТ отставать только потому, что он спит определенное время, в то время как в реальном мире, включая игроков, этого не происходит.

Единственное решение - увеличить баланс ЦП: либо обновить экземпляр, либо уменьшить нагрузку, либо любым другим способом. Экземпляр не будет работать хорошо , когда закончится кредит, точка.

1
22.11.2016, 22:05
3 ответа

Кажется, я понял ответ. Моя проблема, похоже, заключалась в размещении знаков доллара рядом с переменной 'c'. А именно, это сработало:

awk 'NR==FNR{z[$0];next} { if ($3 in z && $4 == "InitFileA"){ c=$3; sub(/-.*/, "", c);$4="InitFileB-"c"-username-ALPHA-password";$5="OutFileB-"c"-username-ALPHA"}}1' ports.lst master.tbl > output.tbl

Теперь, почему это сработало, боюсь, я не могу объяснить. Я буквально хватался за соломинку и приходил в отчаяние. Я прибегал к удалению слоев команды, пока ошибка не исчезла, а затем медленно добавлял команды и возился, пока каждая из них не сработала.

0
27.01.2020, 23:46

У вас есть правильная основная идея разделения задачи на два раунда, но затем вы вызываете awk внутри правила awk .. вот где я перестал читать это слишком сложный способ решения такой простой проблемы.

Рассмотрим этот фрагмент awk:

awk 'BEGIN {
         RS = "[\t\v\f ]*(\r\n|\n\r|\r|\n)";
         FS = "[\t\v\f ]+"
     }

     FNR==1 {
         file++
     }

     /^#/ {
         next
     }

     file==1 {
         port[$1] = $1
     }

     file>=2 && ($3 in port) {
         base = $3;
         sub(/-[^-]*$/, "", base);
         $4 = "InitFileB-" base "-username-ALPHA-password";
         $5 = "OutFileB-" base "-username-ALPHA";
     }

     file>=2 {
         printf "%s\n", $0
     } ' ports.lst master.tbl

Примечание: я добавил необходимые точки с запятой, чтобы вы могли записать все вышеперечисленное в одной строке.

] Если вы запустите вышеуказанное с примерами входных файлов, вы получите

losangeles-P1
losangeles-P3
servername HAWAII-A hawaii-P1 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P2 InitFileB-hawaii-username-ALPHA-password OutFileB-hawaii-username-ALPHA otherfields
servername HAWAII-A hawaii-P4 InitFileA OutFileA otherfields

servername DALLAS-A dallas-P1 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P2 InitFileA OutFileA otherfields
servername DALLAS-A dallas-P3 InitFileA OutFileA otherfields

servername LOSANGELES-A losangeles-P2 InitFileA OutFileA otherfields

Правило BEGIN просто устанавливает универсальную поддержку новой строки в случае, если файлы были перенесены из какой-либо другой системы (например, Windows) с другая кодировка новой строки.

Правило FNR == 1 используется для обновления переменной file , чтобы она отражала обрабатываемый файл (1 для первого, 2 se конд).

Правило / ^ # / {next} пропускает все строки, начинающиеся с решетки.Это комментарии, поэтому их не нужно хранить. Мы также могли бы добавить правило / ^ [\ t \ v \ f] * $ / {next} , чтобы пропустить все пустые строки, если вы хотите сжать выходной файл.

Правило file == 1 {port [$ 1] = $ 1} добавляет все первые поля в первом файле в ассоциативный массив port . Присвоенное значение ( = $ 1 ) не имеет значения, поэтому мы могли бы просто использовать здесь = 0 .

Правило file> = 2 && ($ 3 в порту) применяется ко второму и любым последующим файлам и выполняется, если третье поле совпадает с одним из ключей в ассоциативном массиве port . (Значения не имеют значения; проверяются только ключи.) Другими словами, это правило применяется только тогда, когда третье поле является одним из ключей, указанных в списке портов.

Третье поле копируется в переменную base - это соответствует одному из ключей в порту [] - и всему, что находится после последнего - удаляется с помощью sub () . Затем мы модифицируем четвертое и пятое поля. Обратите внимание, что в awk нет оператора конкатенации строк; мы просто располагаем строки рядом друг с другом. Другими словами, ("foo" a "bar") - это одна строка, состоящая из "foo", за которой сразу следует значение переменной a , преобразованное в строку, за которой сразу следует по "барной стойке".

Последнее правило печатает (возможно, измененную) запись, но гарантирует, что используется \ n перевод строки. Используются только записи во втором и последующих файлах.

Теперь, если ports.lst содержал соответствующие имена пользователей и пароли, я бы немного изменил приведенное выше (может быть, три строки изменились?), но я надеюсь, что вы видите общий подход.

1
27.01.2020, 23:46

Я не выполняю достаточно сценариев на awk, чтобы просто вводить инструкции, но я бы поискал способ использовать структуру «главного» файла и имел несколько блоков.

Концептуальный план решения

BEGIN
{
#  get it ready ...
}

/^$/
{
# maybe just skip lines
# otherwise potential post processing for #Site XX Name
}

/^#Site/
{
# initialize processing for a new site
}

{
# default block for the site processing 'input'
}

FINISH
{
# 'master' is parsed - now fill in the blanks using 'port'
# i.e, start of second pass to complete the work
}

Я знаю, что здесь нет команд awk, но мне также любопытно, считают ли специалисты awk это общим подходом к решениям awk. Слишком часто мне отказывают в использовании awk, потому что я теряюсь в «однострочных операторах awk», то есть в одной команде, которая будет обрабатывать все строки независимо от того, есть ли повторяющиеся блоки ввода.

И даже если это окажется нелепым подходом - я надеюсь, что комментарии просветят меня (и других) так, что я поправлюсь с awk. Спасибо!

0
27.01.2020, 23:46

Теги

Похожие вопросы