Подсчитайте, сколько раз повторяется каждая запись, и выберите минимум и максимум для определенного столбца

#awk

#авк

Вопрос:

1 .- Первый я хотел бы подсчитать, сколько раз появляется каждая запись, ключ — substr ($ 0,20,18), всегда выводите последнюю строку для каждой повторяющейся записи и печатайте в выходном файле в последнем столбце

2. — Найдите минимальное и максимальное значение в столбце 7 и распечатайте в столбцах 4 и 5 в выходном файле.

Input file

 M              G   36829.00  37145.00     1  2161  36840.00  37146.00  37576
M              G   36829.00  37145.00   217  4321  36852.00  37146.00  37576
M              G   36829.00  37145.00   433  6481  36864.00  37146.00  37576
M              G   36829.00  37145.00   649  8641  36876.00  37146.00  37576
M              G   36829.00  37145.00   865 10801  36888.00  37146.00  37576              
M              G   36833.00  38033.00     1  4321  36840.00  37602.00  38464
M              G   36833.00  38033.00   433  8641  36852.00  37602.00  38464
M              G   36833.00  38033.00   865 12961  36864.00  37602.00  38464
M              G   36833.00  38033.00  1297 17281  36876.00  37602.00  38464
M              G   36833.00  38033.00  1729 21601  36888.00  37602.00  38464              
M              G   37265.00  38105.00     1  4321  36840.00  37674.00  38536
M              G   37265.00  38105.00   433  8641  36852.00  37674.00  38536
M              G   37265.00  38105.00   865 12961  36864.00  37674.00  38536
M              G   37265.00  38105.00  1297 17281  36876.00  37674.00  38536
M              G   37265.00  38105.00  1729 21601  36888.00  37674.00  38536
M              G   37265.00  38105.00  2161 25921  36900.00  37674.00  38536             
M              G   37271.00  38885.00     1  2211  36840.00  38454.00  38894
M              G   37271.00  38885.00   222  4421  36852.00  38454.00  38894
M              G   37271.00  38885.00   443  6631  36864.00  38454.00  38894
M              G   37271.00  38885.00   664  8841  36876.00  38454.00  38894
 

Desired Output file

 36829.00  37145.00  10801  36840.00 36888.00  37146.00  37576 5 
36833.00  38033.00  21601  36840.00 36888.00  37602.00  38464 5 
37265.00  38105.00  25921  36840.00 36900.00  37674.00  38536 6 
37271.00  38885.00   8841  36840.00 36876.00  38454.00  38894 4 
 

I tried.

Подсчитать, сколько раз появляется каждая запись.

 awk '{dups[substr($0,20,18)]  } END{for (num in dups) {print num,dups[num]}}' file
 

Чтобы найти минимум и максимум в столбце 7.

 awk '{
      l = substr($7,1,5);
      printf ("]  n",l);
     }' file  |

awk     '               {D1=substr($1, 1, 5)
                         D2=substr($1, 1, 5) 0
                        }
         !(D1 in MIN)   {MIN[D1]=D2
                         MAX[D1]=D2
                         next
                        }
          D2 < MIN[D1]  {MIN[D1]=D2}
          D2 > MAX[D1]  {MAX[D1]=D2}
          END           {for (m in MIN) print m, MIN[m], MAX[m]}
 

Заранее благодарю.

Ответ №1:

Похоже, это то, что вы пытаетесь сделать:

 $ cat tst.awk
{ currKey = $3 FS $4 }
currKey != prevKey { prt(); min=$7; cnt=0 }
{ prevRec=$0; prevKey=currKey; max=$7; cnt   }
END { prt() }

function prt(   f) {
    if ( cnt ) {
        split(prevRec,f)
        print f[3], f[4], f[6], min, max, f[7], f[8], cnt
    }
}

$ sort -k3,4n -k7n file | awk -f tst.awk | column -t
36829.00  37145.00  10801  36840.00  36888.00  36888.00  37146.00  5
36833.00  38033.00  21601  36840.00  36888.00  36888.00  37602.00  5
37265.00  38105.00  25921  36840.00  36900.00  36900.00  37674.00  6
37271.00  38885.00  8841   36840.00  36876.00  36876.00  38454.00  4
 

Комментарии:

1. Г-н Эд, я не понимаю, как вы определяете, например, f [7] для печати значений столбца 7 вместо $ 7, могу ли я использовать для примера [substr $ 7,1] вместо f [7] .. Кстати, я меняю f [7], f [8] на f [8], f [9], чтобы получить желаемый результат. Большое спасибо за вашу помощь

2. @EdMorton Очень умное наблюдение и решение. Вы думаете так, как вы кодируете? 😉

3. не могли бы вы, пожалуйста, объяснить, почему prt(f) вместо просто prt()? оба выдали мне один и тот же результат, как и ожидалось.

4. @acs005 За ваш первый вопрос: спасибо и да — очень просто :-). Для вашего второго: я использую prt( f) для создания локальной переменной с именем f внутри функции prt() (см. gnu.org/software/gawk/manual/html_node/Variable-Scope.html ), что в данном случае не является строго необходимым, но полезно иметь привычку всегда делать это, когда это уместно, чтобы вас не укусили, когда это необходимо.

5. @EdMorton, ценю все объяснения, спасибо большое

Ответ №2:

Не сохраняет порядок входного файла, но работает, даже если ваш файл не упорядочен по ключу первым

 awk '
{
    $7 =0;
    COUNT[$9] =1;
    C1[$9]=$3;
    C2[$9]=$4;
    C3[$9]=$6;
    C6[$9]=$8
}
!($9 in MIN){
    MIN[$9]=$7; 
    MAX[$9]=$7; 
    next
}
$7<MIN[$9]{
    MIN[$9]=$7
}
$7>MAX[$9]{
    MAX[$9]=$7
}
END{
    for(id in COUNT){
        print C1[id], C2[id], C3[id], MIN[id], MAX[id], C6[id], id, COUNT[id]
    }
}' <file>
 

Вывод :

 37271.00 38885.00 8841 36840 36876 38454.00 38894 4
36833.00 38033.00 21601 36840 36888 37602.00 38464 5
36829.00 37145.00 10801 36840 36888 37146.00 37576 5
37265.00 38105.00 25921 36840 36900 37674.00 38536 6
 

Ответ №3:

Не могли бы вы попробовать следующее.

 awk '
{
  val=substr($0,20,18)
  $1=$2=""
  sub(/^[[:space:]] /,"")
}
prev!=val amp;amp; prev{
  print first,second,min,max,third,count
  count=""
}
{
  min=min<$5?min?min:$5:$5
  max=max>$5?max:$5
  prev=val
  count  
  first=$1 OFS $2
  second=$4
  third=$(NF-1) OFS $NF
}
END{
  if(prev){
    print first,second,min,max,third,count
  }
}
'  Input_file | column -t
 

Комментарии:

1. Мистер РавиндерСингх13, спасибо за код, он отлично работает, ценю вашу помощь