gpt4 book ai didi

bash - 如何使用 bash/awk 在列表中找到 X 个最低值?

转载 作者:行者123 更新时间:2023-11-29 09:19:26 27 4
gpt4 key购买 nike

好的,问题是,我有一个包含 N 给定行的列表,如下所示:

4.96035894  2.94014535  9.71651378 On
8.37470259 9.08139103 10.23145322 Off
5.73085411 4.21656546 9.98718707 On
6.40892867 9.44195654 8.83707549 On
4.26065784 3.74966832 7.89520829 On
8.89601431 9.84208918 9.63054539 On
9.10538764 8.58408119 10.87454882 On
6.21494725 4.61164407 9.08378204 Off
7.62256424 9.59449339 10.84506558 Off
6.49210768 4.03768151 10.75221925 Off
5.04079861 4.99362253 10.34349177 Off
...

目标是在第三个字段中找到具有最低值的 X (X < N) 行(它可以很容易地扩展到任何给定的字段,但让我们关注第三个)并更改第四个字段(它总是一个字符串)根据用户调用的参数设置为 On/Off,即如果参数为 On 则更改为 On,如果为 Off 则更改为 Off。

在上面的示例中,如果我想更改为关闭第三个值最低的 3 行,则输出将是:

4.96035894  2.94014535  9.71651378 On
8.37470259 9.08139103 10.23145322 Off
5.73085411 4.21656546 9.98718707 On
6.40892867 9.44195654 8.83707549 Off // this row is changed
4.26065784 3.74966832 7.89520829 Off // this row is changed
8.89601431 9.84208918 9.63054539 On
9.10538764 8.58408119 10.87454882 On
6.21494725 4.61164407 9.08378204 Off // this row is changed
7.62256424 9.59449339 10.84506558 Off
6.49210768 4.03768151 10.75221925 Off
5.04079861 4.99362253 10.34349177 Off
...

我想我可以针对 X=1 的特定情况(最低值行)做,但我不知道如何扩展到任意 X。也许是 X 大小的数组在遍历时填充和编辑名单?

最佳答案

有趣的问题,你需要巧妙地使用数组:

BEGIN {
if (!x) # If x wasn't set using -v default is 3
x=3
if (!field) # If field wasn't set using -v default is 3
field=3
}
{
lines[NR]=$0 # Store each line in an array
sort[NR]=$field # Store the field in an array
field_a[$field]=$0 # Line lookup on field
}
END{
asort(sort) # Sort the fields

for (j=1;j<=NR;j++) { # For every line in the file
for(i=1;i<=x;i++) { # For the top x values
if (lines[j] == field_a[sort[i]]) { # If current line in top x
sub(/On/,"Off",lines[j]) # Do the subsitution
break # Grab the next line
}
}
print lines[j] # print the line
}
}

保存到script.awk等文件中,运行如下:

$ awk -f script.awk file
4.96035894 2.94014535 9.71651378 On
8.37470259 9.08139103 10.23145322 Off
5.73085411 4.21656546 9.98718707 On
6.40892867 9.44195654 8.83707549 Off
4.26065784 3.74966832 7.89520829 Off
8.89601431 9.84208918 9.63054539 On
9.10538764 8.58408119 10.87454882 On
6.21494725 4.61164407 9.08378204 Off
7.62256424 9.59449339 10.84506558 Off
6.49210768 4.03768151 10.75221925 Off
5.04079861 4.99362253 10.34349177 Off

默认情况下,它会关闭字段 3 中最低的 3 个值,但您可以使用 -v 选项指定字段和值的数量。例如,让我们关闭字段 3 中最低的 10 个值,只保留打开的最大值:

$ awk -v x=10 -f script.awk file
4.96035894 2.94014535 9.71651378 Off
8.37470259 9.08139103 10.23145322 Off
5.73085411 4.21656546 9.98718707 Off
6.40892867 9.44195654 8.83707549 Off
4.26065784 3.74966832 7.89520829 Off
8.89601431 9.84208918 9.63054539 Off
9.10538764 8.58408119 10.87454882 On
6.21494725 4.61164407 9.08378204 Off
7.62256424 9.59449339 10.84506558 Off
6.49210768 4.03768151 10.75221925 Off
5.04079861 4.99362253 10.34349177 Off

字段 2 的最大值如何:

$ awk -v x=10 -v field=2 -f script.awk file
4.96035894 2.94014535 9.71651378 Off
8.37470259 9.08139103 10.23145322 Off
5.73085411 4.21656546 9.98718707 Off
6.40892867 9.44195654 8.83707549 Off
4.26065784 3.74966832 7.89520829 Off
8.89601431 9.84208918 9.63054539 On
9.10538764 8.58408119 10.87454882 Off
6.21494725 4.61164407 9.08378204 Off
7.62256424 9.59449339 10.84506558 Off
6.49210768 4.03768151 10.75221925 Off
5.04079861 4.99362253 10.34349177 Off

注意:asort() 函数的使用需要 GNU awk

关于bash - 如何使用 bash/awk 在列表中找到 X 个最低值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16373194/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com