#awk
#авк #awk
Вопрос:
У меня есть текстовый файл с 5 столбцами, которые сгруппированы по содержимому первого столбца. Входные данные выглядят следующим образом:
apple 1 1 1 1
apple 2 1 2 2
apple 4 1 4 4.2
apple 4 1 4 4.5
apple 1 1 1 4.7
apple 2 1 2 5
apple 3 1 3 6
apple 4 1 4 6.5
apple 1 1 1 6.8
apple 2 1 2 7
apple 3 1 3 8
apple 4 1 4 8.5
apple 3 1 3 9
apple 4 1 4 10
banana 25 4 4 1
banana 35 10 14 1.9
banana 36 10 24 2.5
banana 37 10 34 2.6
banana 35 10 14 4
banana 36 10 24 5.5
banana 37 10 34 5.8
banana 25 4 4 7.3
banana 35 10 14 7.5
banana 36 10 24 8
banana 37 10 34 9
banana 37 10 34 10
Для каждой группы в столбце 1 я хотел бы получить только строки со значениями в последнем столбце, которые наиболее близки к числам от 1 до 10.
Например, первой строкой, выбранной для apple, будет строка, в которой значение в столбце 5 ближе всего к 1. Второй выбранной строкой будет та, в которой столбец 5 ближе всего к 2, и так далее до 10. Таким образом, независимо от того, сколько строк для apple на входе, конечный результат будет иметь 10 строк. Из приведенного выше примера желаемый результат будет выглядеть следующим образом:
apple 1 1 1 1
apple 2 1 2 2
apple 2 1 2 2
apple 4 1 4 4.2
apple 2 1 2 5
apple 3 1 3 6
apple 2 1 2 7
apple 3 1 3 8
apple 3 1 3 9
apple 4 1 4 10
banana 25 4 4 1
banana 35 10 14 1.9
banana 37 10 34 2.6
banana 35 10 14 4
banana 36 10 24 5.5
banana 37 10 34 5.8
banana 25 4 4 7.3
banana 36 10 24 8
banana 37 10 34 9
banana 37 10 34 10
Я попробовал несколько вариантов чего-то подобного, что помогло мне частично продвинуться туда, но я не знаю, как выполнить итерацию на основе категорий в первом столбце.
awk '{for (i=1; i<=10; i ) BEGIN{a=100} {aa=i-$5;if (aa<a amp;amp; aa>0) {a=aa;n=$0}} END {print n}}' fruit.txt
Спасибо за любые предложения — я учусь по ходу дела, поэтому пояснения или советы по синтаксису всегда очень ценятся!
Комментарии:
1. Спасибо, что продемонстрировали свои усилия в виде кода в вашем вопросе, продолжайте в том же духе. Переходя к логике получения ожидаемого результата, не могли бы вы подробнее остановиться на логической части для получения ожидаемого результата, поскольку неясно, на каком основании вы хотите игнорировать строки.
2. Привет @RavinderSingh13! Вы вернулись, чтобы снова мне помочь — большое вам спасибо! Я действительно ценю вашу помощь. Я попытался добавить еще несколько пояснений. Я в основном хочу извлечь строки, где значения последнего столбца ближе всего к числам от 1 до 10, так что у меня всегда будет 10 строк на фрукт, независимо от того, сколько строк было на входе. Я надеюсь, что это имеет хотя бы немного смысла!
3. Я понял основную мысль из этого, я считаю, что ваша
banana
фруктовая 2-я строка должна иметь2.5
, а не1.9
правильно? Пожалуйста, подтвердите меня один раз, в любом случае я добавил ответ и здесь, мы могли бы обсудить там, приветствия.4. если у вас есть одна строка в файле,
apple 1 1 1 1
ожидаете ли вы 10 xapple 1 1 1 1
на выходе?5. Да, это совершенно верно @perreal! Поэтому при сравнении 1 с числами через 1-10 это всегда будет ближайшее число, если это единственная запись. Каждый фрукт должен содержать 10 строк, даже если строки повторяются, чтобы получить это. Я надеюсь, что это имеет смысл!
Ответ №1:
Требуется GNU awk для массивов массивов.
function abs(v) {return v < 0 ? -v : v}
{
for (i = 1; i <= 10; i ) {
if (a[$1][i] == "" || abs(i - $5) < a[$1][i]) {
b[$1][i] = $0;
a[$1][i] = abs(i - $5)
}
}
}
END {
for (k in b) {
for (i = 1; i <= 10; i) {
print b[k][i]
}
}
}
Дает:
apple 1 1 1 1
apple 2 1 2 2
apple 3 1 3 3
apple 4 1 4 4.2
apple 2 1 2 5
apple 3 1 3 6
apple 2 1 2 7
apple 3 1 3 8
apple 3 1 3 9
apple 4 1 4 10
banana 25 4 4 1
banana 35 10 14 1.9
banana 25 4 4 3
banana 35 10 14 4
banana 36 10 24 5
banana 37 10 34 6
banana 25 4 4 7.3
banana 36 10 24 8
banana 37 10 34 9
banana 37 10 34 10