2017-02-22 43 views
-1

У меня есть файл, где я хотел выбрать строки, где столбец $ 3 одинаковый. Теперь я сгруппировал их, но я хочу сделать определенные действия над этими строками в случае, если столбец $ 1 (и/или $ 2) удовлетворяет определенному условию.Выбор совпадающих столбцов и действий на этих линиях

Например, если все значения в $ 1 и $ 2 (внутри группы строк, которые имеют одинаковое значение в $ 3), находятся в пределах 0,1 друг от друга, я хочу взять среднее число столбцов $ 1 и $ 2 (для этого группа, которая имеет тот же $ 3). Если он больше, я хочу просто распечатать эти строки, не принимая в среднем.

Мой вход что-то вроде:

1.3 22.5 ALFA 45 50 
1.4 22.6 ALFA 45 50 
1.5 22.7 ALFA 45 50 
1.6 22.8 ALFA 45 51 
5.5 8.5 BETA 53 15 
5.6 8.6 BETA 53 15 
5.5 8.5 BETA 53 15 
7.6 10.6 GAMA 75 13 
7.7 10.7 GAMA 76 13 
12 11.5 GAMA 75 13 
4.5 4.5 DELTA 65 12 
4.6 5.7 DELTA 65 12 
12.1 8 EPS 44 16 
12.2 8 EPS 44 16 

Я хочу, чтобы мой выход будет:

out1.txt:

5.53 8.53 BETA 53 15 
12.15 8 EPS 44 16 

out2.txt:

1.3 22.5 ALFA 45 50 
1.4 22.6 ALFA 45 50 
1.5 22.7 ALFA 45 50 
1.6 22.8 ALFA 45 50 
7.6 10.6 GAMA 75 13 
7.7 10.7 GAMA 76 13 
12 11.5 GAMA 75 13 
4.5 5.6 DELTA 65 12 
4.6 9  DELTA 65 12 
+0

образец ввода/вывода поможет вам получить больше ответов и проверить скрипты. Это кажется тривиальным упражнением для 'awk' – karakfa

+0

Возможно, я был неясен в вопросе. У меня нет скрипта для проверки, я просто не знаю, как написать его для выбора строки, когда я не выбираю определенный шаблон, а только определенное соответствие. –

+0

люди могут проверить свои собственные сценарии независимо от того, соответствует ли он вашему выходу или нет. Написание хорошей спецификации - нетривиальное упражнение. Например, что, если ваши значения в 3 доллара заполняют диапазон «0,9 0,95 1 1,05 1,1 1,1 1,2» или группируются вокруг двух значений? (бимодальный) '0,9 1,1 0,95 2 2,01 1,91' – karakfa

ответ

0

awk к r escue!

awk '{k=$3; 
     if(!(k in min1)) {max1[k]=min1[k]=$1; max2[k]=min2[k]=$2} 
     sum1[k]+=$1; sum2[k]+=$2; count[k]++; 
     if(max1[k]<$1) max1[k]=$1; if(min1[k]>$1) min1[k]=$1; 
     if(max2[k]<$2) max2[k]=$2; if(min2[k]>$2) min2[k]=$2}  
    END {for(k in sum1) 
      if(max1[k]-min1[k]<=0.1 && max2[k]-min2[k]<=0.1) 
       printf "%.2f\t%.2f\t%s\n",sum1[k]/count[k],sum2[k]/count[k],k}' file 

12.15 8.00 EPS 
5.53 8.53 BETA 

много кода, но почти тривиально, порядок не сохраняется.

+0

Спасибо! И если бы у меня было больше столбцов в моем исходном файле, как я мог бы их распечатать? Как в отредактированном вопросе ввода/вывода. Использование sth like 'print {$ 4, $ 5}' выводит те же значения столбцов 4 и 5 для каждой строки вместо соответствующей строки –

+0

, что проще всего сделать их частью ключа. измените на 'k = $ 3 FS $ 4 FS $ 5'. В какой-то момент вам придется голосовать и принимать ответы. В противном случае люди перестанут отвечать на ваши вопросы. – karakfa

+0

Хорошо. А min1 и min2 в этом случае являются awk-функциями для минимума и максимума или имен значений? –

Смежные вопросы