Используя awk
, мы можем решить эту проблему, используя substr
:
substr(s, m[, n ])
: Возврат не более n
-строка подстрока s
, которая начинается в позиции m
, нумерация от 1. Если n
опущен или если n
указывает больше символов, чем осталось в строке, длина подстроки должна быть ограниченапо длине строки s
.
Это позволяет нам взять строку, которая представляет число.Здесь я предположил, что знак до и после числа одинаков и, следовательно, знак числа:
$ echo "10000000001000000000053009-000000000053009-" \
| awk '{print length($0); print substr($0,27,43-27)}'
43
-000000000053009
Поскольку awk
неявно преобразует строки в числа, если вы выполняете над ними числовые операции, мы можем написатьследующий awk
-код для достижения запрошенного:
$ awk '/header|trailer/{next}
{s+=substr($0,27,43-27)}
END{print s}' file.dat
-5421749244
или в одну строку:
$ awk '/header|trailer/{next}{s+=substr($0,27,43-27)} END{print s}' file.dat
-5421749244
Приведенные выше примеры работают только с файлом примера, заданным OP.Однако, если у вас есть файл, содержащий несколько блоков с header
и trailer
, и вы хотите использовать только текст внутри этих блоков (исключая все, что находится за пределами блоков), то вы должны обработать его немного по-другому:
$ awk '/header/{s=0;c=1;next}
/trailer/{S+=s;c=0;next}
c{s+=substr($0,27,43-27)}
END{print S}' file.dat
Здесь мы делаем следующее:
- Если найдена строка с
header
, сбросьте сумму блоков s
на ZERO
и установите c=1
, указывая, что мыпримите во внимание следующие строки - Если найдена строка с
trailer
, добавьте сумму блоков s
к общей сумме S
и установите c=0
, указывая на игнорирование строк. - Если
c/=0
вычислить сумму блока s
- В поле
END
выведите общую сумму S