Поиск минимального и максимального значения из столбца одного столбца и соответствующего значения из другого

Это просто в оболочках, поддерживающих подстановку процессов , например. баш

$ echo foo | tee >(xsel)
foo
$ xsel -o
foo

В противном случае вы можете использовать FIFO (, хотя это не удобно)

$ mkfifo _myfifo
$ xsel < _myfifo &
$ echo bar | tee _myfifo
bar
$ xsel -o
bar
[1] + Done                       xsel 0<_myfifo
$ 

0
01.08.2019, 13:05
3 ответа
$ cat tst.awk
BEGIN { OFS="\t" }
NR==1 { next }
NR==2 { maxVal = $2 }
NR==FNR {
    if ($2 >= maxVal) {
        maxSth = $1
        maxVal = $2
    }
    next
}
{ print (FNR>1 ? ($1 - maxSth) : $1), $2 }

$ awk -f tst.awk file file
[s]     [K]
-5      900
-4      100
-3      200
2       1000
-5      80
49      12
0       90000
-1      1
0
28.01.2020, 02:39

может что-то вроде этого? Обратите внимание на файл обработки дважды.

awk 'NR==FNR && NR>1 { max_col2=( max_col2>$2?max_col2:$2 ); max[$2]=$1;  
                       min_col1=( min_col1>$1?min_col1:$1 ); min[$1]=$2; }
     NR!=FNR && FNR>1{ print $1-max[max_col2], $2-min[min_col1]; }' OFS='\t' infile infile
-5      888
-4      88
-3      188
2       988
-5      68
49      0
0       89988
-1      -11
0
28.01.2020, 02:39

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

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
2
28.01.2020, 02:39

Теги

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