
我想找到B列的最大值和保留 B 列值等於或大於最大值 20% 的所有行。
輸入資料
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
期望的輸出
A B C D E
2 79 56 SD L
9 60 37 KD G
我嘗試過使用awk 'BEGIN {max = 0} {if ($2>max) max=$2} END {if ($2 >= (0.1*max)) print}' file_in > file_out
,但這只會列印出文件的最後一行。
答案1
您需要將所有行保存在數組中,以便能夠在END{ }
.或者,掃描文件兩次。因此,保存所有值和行:
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
答案2
和磨坊主:
1)漂亮的列印資料:
$> mlr --from data --ipprint --otsv cat
A B C D E
2 79 56 SD L
9 60 37 KD G
2)將欄位的最大值新增B
至欄位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) 過濾線其中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)然後再cut
離開B_max
:
$> 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