Присвойте переменную оператору awk '{if ...}' в цикле while - PullRequest
1 голос
/ 01 мая 2020

Я изо всех сил пытаюсь использовать переменную, которую я установил в while loop для awk.

Например, у меня есть файл, который содержит это:

1-WW
(2, 17.0)       (3, 25.0)       (4, 32.0)       (5, 37.0)       (6, 42.0)       (7, 46.0)       (8, 50.0)       (9, 53.0)       (10, 56.0)      (11, 59.0)      (12, 62.0)      (13, 65.0)   (14, 67.0)    (15, 70.0)       (16, 72.0)      (17, 74.0)      (18, 77.0)      (19, 79.0)      (20, 81.0)      (21, 83.0)      (22, 84.0)      (23, 86.0)      (24, 88.0)      (25, 89.0)      (26, 90.0)   (27, 90.0)
5-Ferm
(2, 16.0)       (3, 24.0)       (4, 29.0)       (5, 34.0)       (6, 37.0)       (7, 41.0)       (8, 43.0)       (9, 46.0)       (10, 48.0)      (11, 50.0)      (12, 52.0)      (13, 54.0)      (14, 56.0)      (15, 58.0)      (16, 59.0)

Цель из l oop: to:

  1. Возьмите строку, которая начинается с "^(" и превратите ее в текстовый файл с двумя столбцами -DONE
  2. Сортировка файла по столбцу два и присвойте максимальное значение переменной с именем max -DONE
  3. Найдите строки в столбце 2 == $max, найдите значения min столбца $ 1 и добавьте к выводу -HELP!

Я сделал oop, как показано ниже. Это довольно неуклюже, поскольку я довольно плохо знаком с bash и все еще очень много учусь! Я пытаюсь вызвать мою переменную $max в последнюю строку awk. Любой совет будет приветствоваться!

Я использую while loop, так как фактический файл, который я буду использовать, содержит несколько строк, как в примере выше, и я хочу сделать этот процесс для каждой строки, которая начинается с "^(" Я перепробовал множество вариантов назначения переменной в awk, следуя многим ответам на приведенные здесь вопросы, но я не могу заставить их работать!

#!/usr/bin/env bash

# read through all lines and if the start with "(" do ...
while IFS='\t' read -r LINE || [ -n "${LINE}" ]; do
        if [[ "${LINE}" == "("* ]]; then
                echo "line: ${LINE}"; # print out line to make sure correct
                echo "${LINE}" | xargs -n 2 | sed 's/(//g' | sed 's/)//g' | awk -F"," '$1=$1' OFS="\t" > loop_test; # make all (,) into two columns and read into loop_test
                cat loop_test;
                max= sort -nrk2,2 loop_test | awk '{print $2}' | head -n 1 # sort by columns 2 and find largest value - input to variable max
                echo $max # check variable max has been assinged
                awk -v var="$max" '{ if ($2 == var) { print } }' loop_test | sort -nrk1,1 | tail -n 1 | awk '{print $1}' >> out # now find all rows where column 2 = $max and find lowest value of column 1 - send value to ouptut
        fi
done < test

Ожидаемый результат должен быть файлом с именем out вот так:

26
16

Заранее благодарю за помощь и предложения:)

1 Ответ

1 голос
/ 01 мая 2020

С любым POSIX awk:

$ cat tst.awk
BEGIN { FS="[)(,[:space:]]+" }
/^\(/ {
    delete vals
    max = $3
    vals[$3] = $2
    for (i=5; i<=NF; i+=2) {
        if ( $i > max ) {
            max = $i
            vals[$i] = ($i in vals ? vals[$i] " " : "") $(i-1)
        }
    }
    split(vals[max],p)
    min = p[1]
    for (i in p) {
        min = (p[i] < min ? p[i] : min)
    }
    print min
}

$ awk -f tst.awk file
26
16
...