Вам нужно будет выполнить два прохода по вашим данным, чтобы сначала найти минимальное и максимальное значения, а затем выполнить вычисления:
awk 'BEGIN { OFS = "\t" }
FNR == NR { if (FNR > 1 && (min == "" || $2 < min)) { min = $2; minval = $1 }
if (FNR > 1 && (max == "" || $2 > max)) { max = $2; maxval = $1 }
next }
FNR == 1 { print "[s (-max)]", "[s (-min)]", "[K]"; next }
{ print $1 - maxval, $1 - minval, $2 }' file file
Для заданных данных это даст
[s (-max)] [s (-min)] [K]
-5 -4 900
-4 -3 100
-3 -2 200
2 3 1000
-5 -4 80
49 50 12
0 1 90000
-1 0 1
Код awk
имеет четыре блока, и мы передаем ему входной файл дважды . Первый блок(BEGIN
)просто устанавливает разделитель полей вывода на символ табуляции.
Второй блок(FNR == NR
)будет выполняться для каждой строки во время первого прохода по файлу и отслеживает максимальные и минимальные значения во 2-м столбце(max
иmin
)и соответствующие значения в 1-м столбце.(maxval
и minval
), обновляя их по мере необходимости. В конце этого блока next
используется для пропуска остальной части скрипта для текущего ввода.
NR
— порядковый номер текущей записи (— «номер строки» )в целом, а FNR
— тот же номер для текущего файла. NR
будет таким же, как FNR
, только для первого прохода по входному файлу.
Третий блок(FNR == 1
)будет выполняться, когда будет только что прочитана первая строка из второго прохода по файлу. Он просто печатает заголовок. Мы собираемся вычислить вычитание значений minval
и maxval
из значения 1-го столбца, поэтому мы добавляем новый заголовок столбца.
Последний блок является безусловным и будет выполняться со 2-й строки и далее во 2-м проходе по файлу, выполняя фактические вычисления и вывод данных.
Вы можете получить немного более красивый вывод, пропустив вывод черезcolumn -s $'\t' -t
:
[s (-max)] [s (-min)] [K]
-5 -4 900
-4 -3 100
-3 -2 200
2 3 1000
-5 -4 80
49 50 12
0 1 90000
-1 0 1