Tome el valor máximo de una columna y extraiga todas las líneas con al menos el 20% de este valor

Tome el valor máximo de una columna y extraiga todas las líneas con al menos el 20% de este valor

Me gustaría encontrar el valor máximo de la columna B.Ymantenga todas las líneas donde los valores de la columna B sean 20% o más del máximo.

DATOS DE ENTRADA

A B C D E
2 79 56 SD L
1 09 67 JK S
9 60 37 KD G
0 10 47 SO E

SALIDA DESEADA

A B C D E
2 79 56 SD L
9 60 37 KD G

Intenté usarlo awk 'BEGIN {max = 0} {if ($2>max) max=$2} END {if ($2 >= (0.1*max)) print}' file_in > file_outpero esto solo imprime lo que parece ser la última línea de mi archivo.

Respuesta1

Debe guardar todas las líneas de una matriz para poder revisarlas nuevamente en el archivo END{ }. O, alternativamente, escanee el archivo dos veces. Entonces, guardando todos los valores y líneas:

awk 'NR == 1 {header=$0; next}            # save the header            
  { lines[NR]  = $0; values[NR] = $2;     # save the line and 2nd field
    if ($2 > max) max = $2; }             # update max

  END { print header;                     # in the end, print the header
        for (i = 1 ; i <= NR ; i++)  {    # (we skipped line 0)
          if (values[i] >= max * 0.2)     # print lines where $2 was high enough
            print lines[i]; } } ' file_in 

Respuesta2

Conmolinero:

1) Datos bonitos:

$> mlr --from data --ipprint --otsv cat
A   B   C   D   E
2   79  56  SD  L
9   60  37  KD  G

2) Agregue el máximo de campo Bal campo B_max:

$> mlr --from data --ipprint --otsv stats1 -a max -f B -s -F
A   B   C   D   E   B_max
2   79  56  SD  L   79.000000
1   09  67  JK  S   79.000000
9   60  37  KD  G   79.000000
0   10  47  SO  E   79.000000

3) Filtrar líneas donde B >= B_max * 0.2:

$> mlr --from data --ipprint --otsv stats1 -a max -f B -s -F then filter '$B >= $B_max*0.2'
A   B   C   D   E   B_max
2   79  56  SD  L   79.000000
9   60  37  KD  G   79.000000

4) Luego cutlejos B_maxde nuevo:

$> mlr --from data --ipprint --otsv stats1 -a max -f B -s -F then filter '$B >= $B_max*0.2' then cut -x -f B_max
A   B   C   D   E
2   79  56  SD  L
9   60  37  KD  G

información relacionada