2016-06-08 3 views
0

У меня есть текстовый файл, который выглядит ниже. Первый столбец - это местоположение, второе - позиция, а третье - значение.Bash Awk: Медиана над окнами с позициями начала и остановки

1 10 200 
1 11 150 
1 12 300 
2 13 400 
2 14 100 
2 15 250 
3 16 200 
3 17 200 
3 18 350 
3 19 150 
... 

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

1 2 10 13 250 
2 3 14 17 200 
... 

Для каждого окна (4 строки), первое значение (в пределах окна) первого столбца, последнего значения (в пределах окна) первого столбца, первое значение второго столбца, последнее значение второго столбца и медиана третьего столбца.

У меня есть частично работающий. Нижеприведенный сценарий печатает последнюю позицию столбца 1, последнюю позицию столбца 2 и означает.

win=4 
cat file.txt | awk -v win="$win" '{sum+=$3} (NR%win)==0 {print $1,$2,sum/win;sum=0}' 

2 13 262.5 
3 17 187.5 
... 

Как получить начальные позиции в каждом окне и медианное?

ответ

2
$ awk '{r=(NR-1)%4; a[r]=$3} 
    r==0{f1=$1; s1=$2} 
    r==3{asort(a); print f1,$1,s1,$2,(a[2]+a[3])/2; delete a}' file 

1 2 10 13 250 
2 3 14 17 200 

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

вы можете параметризовать размер окна, нужно обрабатывать четное/нечетное

$ awk -v w=5 '{r=(NR-1)%w; a[r]=$3} 
      r==0{f1=$1; s1=$2} 
     r==(w-1){asort(a); 
       print f1,$1,s1,$2,(w%2?a[int(w/2)+1]:(a[w/2]+a[w/2+1])/2); 
       delete a}' file 

1 2 10 14 200 
2 3 15 19 200 

Безразлично 't, если последнее окно не в полном размере

+0

thats cool! именно то, что я искал. Можно ли проверить, чтобы игнорировать/пропускать окна меньше, чем размер окна? – rmf

+1

Это будет игнорировать последний частичный блок, для некоторой дополнительной логики создайте блок «END» и проверьте, меньше ли r (w-1), что будет означать частичный последний блок и отчет соответственно. – karakfa