Я пытаюсь напечатать все максимальные значения
так, если текст выглядит как
'''
имя1 работа1 9500.
имя2 работа2 9500.
имя3 задание3 4500.
'''
Я хочу распечатать это как
'''
job: job1, sal: 9500
job: job2, sal: 9500
''''
пока что мой код
'''
BEGIN {a=0}
{if ($3> a)
max=$3;
output=$2
}
END{
print "job: ", output, "sal:", max}
'''
и результат, который я получаю,
'''
job: job2, sal: 9500
'''
пожалуйста, обновите вопрос, чтобы включить (неправильный) вывод, сгенерированный вашим кодом; также подумайте о том, чтобы подробно просмотреть свой код... 1) похоже, что вы отслеживаете максимальное значение с двумя разными переменными (a
и max
)... 2) команда print
генерирует что-то другое (4 токена в строке) из то, что вы сказали, должно быть в ожидаемом результате (2 токена в строке)
ввод уже отсортирован по 3-му столбцу в порядке убывания (как показано в вашем образце ввода)?
Одним из способов может быть отслеживание максимального числа, и если у вас есть число выше, сохраните это число.
Если это та же сумма, что и текущее число, то отслеживайте эти строки (поле 2 и поле 3) в массиве и в конце печатайте их.
awk '
{
if ($3 > max) {
max = $3
i = 0;
lines[++i] = $2 OFS $3
next;
}
if ($3 == max) lines[++i] = $2 OFS $3
}
END {
for (j=1;j<=i; j++) print lines[j]
}' file
Вывод
job1 9500
job2 9500
Спасибо за твой ответ! Но я пытаюсь напечатать его как job: job1 sal: 9500. job: job2 sal: 9500. Ваш код работает нормально, когда я пытаюсь просто напечатать поле 2,3. Но это не работает, когда я пытаюсь напечатать его так, как я хочу
@wannabe В этом случае вы можете написать нужный формат как lines[++i] = "job: " $2 OFS ", sal: " $3
Вот двухпроходное решение awk, поэтому весь файл не должен находиться в памяти:
awk 'FNR==NR{max=$3>max ? $3 : max; next}
$3==max {print $2, $3}' file file
Отпечатки:
job1 9500
job2 9500
вам не нужен 2-проход, и вам не нужно предварительно помещать все это в память:
echo "${input}" | gsort -n | gtee >( gpaste - >&2; ) |
mawk '+_ <= +(__=$3) { if (+_<+__) {
split("",___)
_ = __
____ = NR
} ___[NR] = $2 OFS __
} END {
for (_=____;_<=NR;_++) { if (_ in ___) {
print ___[_] } } } ' | gcat -n | ecp
name1 job1 9500.
name2 job2 9500.
name3 job3 4500.
1 job1 9500.
2 job2 9500.
echo "${input}" | gsort -nr | gtee >( gpaste - >&2; ) |
gawk '+_ <= +(__=$3) { if (+_<+__) {
split("",___)
_ = __
} ___[NR] = $2 OFS __
} END {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (_ in ___) {
print ___[_] } } ' | gcat -n | ecp
name3 job3 4500.
name2 job2 9500.
name1 job1 9500.
1 job2 9500.
2 job1 9500.
Потому что, когда вам нужны только те, которые соответствуют максимальному значению, просто сохраните строки, соответствующие вашему текущему максимальному значению,
поэтому всякий раз, когда обнаруживается новый максимум, все ранее сохраненные строки больше не подходят, поэтому просто очистите весь массив (split("", arr)
) и начните заново, обновляя переменную состояния, отмечая текущий номер строки (NR
), чтобы вы не нужно зациклить весь путь от 1
Если вход также содержит отрицательные значения, тогда установите начальное состояние "_"
на log(0) aka neg. infinity
- обратите внимание на разницу между
mawk
иgawk
версиями кода
Пожалуйста, четко форматируйте свой код, когда просите других людей прочитать его, чтобы помочь вам. Запустите
gawk -o-
на нем, если вы не знаете, как это сделать.