У меня есть несколько файлов чертежей в формате, описанном ниже. Мне нужно увеличить значение числа в области файла ниже после строки BO . Все значения (в примере ниже), равные 14,00, необходимо увеличить на 1 до 15,00. В этом случае 5 строк ниже BO станут 15.00. Я вижу, что $ 4 + 1
увеличит значение, однако два десятичных знака отсутствуют.
Я вижу, что gawk допускает выражения, подобные C, поэтому это было бы решением. Я не могу понять, как обнаружить запись BO и затем манипулировать полями, пока не будет достигнут EN
.
Приветствуются любые советы о том, как этого можно достичь.
Спасибо.
AK
v 0.00u 0.00 0.00 0.00 0.00 0.00 0.00
398.56 0.00 0.00 0.00 0.00 0.00 0.00
398.56 50.00 0.00 0.00 0.00 0.00 0.00
0.00 50.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00
BO
v 25.00o 18.75 14.00
v 75.00o 18.75 14.00
v 323.56o 18.75 14.00
v 373.56o 18.75 14.00
EN
Это может быть достигнуто за счет использования очень простой -машины состояний:
$ awk -v OFS="\t" '/^[A-Z][A-Z]/ && !/^BO/ { flag=0 } /^BO/ { flag=1 } flag == 1 && NF == 4 { $4 = sprintf("%.2f", 1+$4) } { print }' file
AK
v 0.00u 0.00 0.00 0.00 0.00 0.00 0.00
398.56 0.00 0.00 0.00 0.00 0.00 0.00
398.56 50.00 0.00 0.00 0.00 0.00 0.00
0.00 50.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00
BO
v 25.00o 18.75 15.00
v 75.00o 18.75 15.00
v 323.56o 18.75 15.00
v 373.56o 18.75 15.00
EN
Сценарий ничего не делает, кроме как передает ввод к выводу, пока не дойдет до строки, начинающейся с BO
, затем устанавливает flag
в 1.
Если flag
равно 1 и текущая строка содержит четыре столбца, четвертый столбец переформатируется с использованием sprintf()
и 1+$4
. Спецификация формата %.2f
означает «значение с плавающей запятой с двумя десятичными разрядами».
Если в начале строки найдено что-то отличное от BO
, flag
сбрасывается на ноль.
Заполнение между столбцами изменяется в выходных строках, где была сделана модификация. Это связано с тем, что awk
разбивает поля на пробелы, а затем объединяет их, используя OFS
(, установленный здесь как символ табуляции ), когда происходит вывод.
Чтобы получить точно такой же выходной формат, как и входной, вы можете сделать что-то вроде
$ awk -v OFS="\t" '/^[A-Z][A-Z]/ && !/^BO/ { flag=0 } /^BO/ { flag=1 } flag == 1 && NF == 4 { printf("%3s %11s%10.2f %10.2f\n", $1,$2,$3,1+$4); next } { print }' file
AK
v 0.00u 0.00 0.00 0.00 0.00 0.00 0.00
398.56 0.00 0.00 0.00 0.00 0.00 0.00
398.56 50.00 0.00 0.00 0.00 0.00 0.00
0.00 50.00 0.00 0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.00 0.00
BO
v 25.00o 18.75 15.00
v 75.00o 18.75 15.00
v 323.56o 18.75 15.00
v 373.56o 18.75 15.00
EN