#awk
#awk
Вопрос:
A есть файл:
file.txt 1 32 2 34 3 32 4 43 5 25 6 34 7 65 8 34 9 23 10 44
Я хотел бы найти аномалию в столбце «Отправить»:
мой приведенный ниже сценарий печатает аномалии с учетом значений от 2 до 10 строк. Он не учитывает значения строки 1.
awk 'FNR==NR{ f=1; if($1 gt;= 1 amp;amp; $1 lt;= 10){ count ; SUM =$2; }; next } FNR==1 amp;amp; f==1{ AVG=SUM/count; next } ($1 gt;= 1 amp;amp; $1 lt;= 10){ print $1, $2-AVG } ' file.txt file.txt
Результат моего желания:
1 -4.6 2 -2.6 3 -4.6 4 6.4 5 -11.6 6 -2.6 7 28.4 8 -2.6 9 -13.6 10 7.4
У меня есть решение этой проблемы:
awk '{f=$1gt;=1 amp;amp; $1lt;=10}f amp;amp; NR==FNR{sum =$2; c ; next}f{ print $1, $2-(sum/c) }' file.txt file.txt
Я все еще задаюсь вопросом, почему первый сценарий не дает правильного ответа.
Комментарии:
1. Что вы имеете в виду под аномалией? Вы имеете в виду отклонение от среднего значения?
2. ДА. Это отклонение от среднего значения. Спасибо.
3. Первый сценарий не дает правильного значения, потому что вы пропускаете первую строку при втором проходе вашего файла
(FNR==1 amp;amp; f==1) { AVG=sum/count; next }
. Из-за следующего утверждения вы пропускаете вычисление отклонения от среднего значения для первой записи.
Ответ №1:
Поскольку это всего лишь файл с 2 столбцами, это также можно сделать за один проход awk
:
awk '{map[$1] = $2; s = $2} END {mean = s/NR; for (i in map) print i, map[i] - mean}' file 1 -4.6 2 -2.6 3 -4.6 4 6.4 5 -11.6 6 -2.6 7 28.4 8 -2.6 9 -13.6 10 7.4
Комментарии:
1. Здесь есть пара проблем: (а) возникает проблема, когда несколько строк имеют одинаковое значение в первом столбце. (b) цикл for не пересекает индексы в том же порядке, в каком вы их добавляете (c) Я знаю, что вы все это знаете 😉
2. Вы абсолютно правы и придерживаетесь своего ответа 🙂
Ответ №2:
Первый сценарий в операции не дает правильного значения, потому что вы пропускаете первую строку во втором проходе вашего файла. Это видно из заявления (FNR==1 amp;amp; f==1) { AVG=sum/count; next }
. Из-за этого next
утверждения вы пропускаете вычисление отклонения от среднего значения для первой записи.
Это эффективное вычисление отклонения от среднего значения за двойной проход:
awk '(NR==FNR){s =$2;c ;next} (FNR==1){s/=c} {print $1,$2-s}' file file
Если file
содержит значения больше 10 или меньше 1 в первом столбце, но вы хотите видеть это только для значений в диапазоне [0,10]
, то вы можете сделать:
awk '($1lt;1 || $1gt;10) {next} (NR==FNR){s =$2;c ;next} (FNR==1){s/=c} {print $1,$2-s}' file file
Есть еще другие оптимизации, которые можно выполнить, но они становятся полезными только при работе с очень большими файлами (многие миллионы строк).
Комментарии:
1. Да, файл содержит 100 строк (на самом деле это годы), и я искал 1-ю аномалию за 10 лет. Спасибо, что прояснили это…