Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 如何根据第四列为每个ID选择包含指数值的最小值?_Sorting_Awk - Fatal编程技术网

Sorting 如何根据第四列为每个ID选择包含指数值的最小值?

Sorting 如何根据第四列为每个ID选择包含指数值的最小值?,sorting,awk,Sorting,Awk,您能告诉我如何在linux中基于第四列和按第一列分组选择最小值(包括指数)的行吗 原始文件 ID,y,z,p-value 1,a,b,0.22 1,a,b,5e-10 1,a,b,1.2e-10 2,c,d,0.06 2,c,d,0.003 2,c,d,3e-7 3,e,f,0.002 3,e,f,2e-8 3,e,f,1.0 我想要的文件如下 ID,y,z,p-value 1,a,b,1.2e-10 2,c,d,3e-7 3,e,f,2e-8 实际上这很好,谢谢大家 tail -n +2

您能告诉我如何在linux中基于第四列和按第一列分组选择最小值(包括指数)的行吗

原始文件

ID,y,z,p-value
1,a,b,0.22
1,a,b,5e-10
1,a,b,1.2e-10
2,c,d,0.06
2,c,d,0.003
2,c,d,3e-7
3,e,f,0.002
3,e,f,2e-8
3,e,f,1.0
我想要的文件如下

ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8
实际上这很好,谢谢大家

tail -n +2 original_file > txt sort -t, -k 4g txt | awk -F, '!visited[$1]++' | sort -k2,2 -k3,3 >> final_file

awk
中,只需将当前记录保留为给定的第1个字段的最小第4个字段,就可以相当轻松地完成此操作。您必须处理输出标题行并存储第一条记录以开始比较,这可以通过操作第一条记录
NR==1
(或在处理的每个文件中的第一条,
FNR==1
)来完成

您可以将第一个最小值存储在由第一个字段索引的数组中,并保存包含对第二个记录进行操作的值的初始记录。然后,只需检查第一个字段是否与最后一个字段不同,如果是,则输出最后一个字段的最小记录,并继续执行,直到记录用完为止。(注意:这假定第一个字段按文件中的顺序递增)然后使用
END
规则输出最终记录

您可以将其组合如下:

awk -F, '
    FNR==1 {print; next}
    FNR==2 {rec=$0; m[$1]=$4; next}
    {
        if ($1 in m) {
            if ($4 < m[$1]) {
                rec=$0
                m[$1]=$4
            }
        }
        else {
            print rec
            rec=$0
            m[$1]=$4
        }
    }
END {
    print rec
}' file

仔细检查一下,如果您有问题,请告诉我。

非awk方法,使用:

$datamash-H-f-t,-g1分钟4
(需要
cut
,因为使用
-f
选项
datamash
会添加第五列,它是第四列的副本;没有它,它只会显示第一列和第四列的值。小麻烦。)


这确实需要将您的数据按样本中的第一列进行排序。

欢迎访问,请添加您为解决您自己的问题所付出的努力,然后通知我们。事实上,我尝试了以下方法。但这不适用于“E-8”或那些指数值。tail-n+2原始文件>txt排序-t,-k 4n txt | awk-F'!已访问[$1]+'| sort-k2,2-k3,3>>最终文件感谢您告知您的努力,请将其添加到您的问题中。非常感谢您的帮助。但这不是E-8或E-10。所以这只处理如下的值。。。我想我们需要加上-gID,y,z,p值1,a,b,0.22 2,c,d,0.06 2,c,d,0.003 3,e,f,0.002 3,e,f,1.0``当你说“不读e-8或e-10”时,我有点困惑,当我在你的行上运行时,我得到了返回的
1,a,b,0.22 2,c,d,0.003 3,e,f,0.002
(看起来应该是这样的???)你是说
“e-8”而不是
?另外,在注释中的文本周围只有一个
`
,突出显示为code
:)
谢谢您的快速回复。原始文件如下所示ID,y,z,p值1,a,b,0.22 1,a,b,5e-10 1,a,b,1.2e-10 2,c,d,0.06 2,c,d,0.003 2,c,d,3e-7 3,e,f,0.002 3,e,f,2e-8 3,e,f,1.0“我尝试了你教我的代码,但结果如下…”ID,y,z,p值1,a,b,0.22 2,c,d,0.003 3,e,f,0.002`我想得到如下结果ID、y、z、p值1、a、b、1.2e-10 2、c、d、3e-7 3、e、f、2e-8`如果您在Linux上,一个快速测试是复制问题中的文本,然后在终端
cat数据文件中按return并将文本粘贴到终端中。然后在第一个空白行键入
EOF
,然后按return。这将为您的文件创建一个正确的ASCII版本以供使用。现在对数据文件运行
awk
命令。如果您在Win10中使用WSL,也可以在那里使用。无法使用windows编辑器进行保存(除非更改了默认的行尾并选择UTF-8作为字符集-选择ASCII更安全),请参见:和
em-dash
en-dash
。如果在windows上也可以。
$ awk -F, '
>     FNR==1 {print; next}
>     FNR==2 {rec=$0; m[$1]=$4; next}
>     {
>         if ($1 in m) {
>             if ($4 < m[$1]) {
>                 rec=$0
>                 m[$1]=$4
>             }
>         }
>         else {
>             print rec
>             rec=$0
>             m[$1]=$4
>         }
>     }
> END {
>     print rec
> }' file
ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8
$ datamash -H -f -t, -g1 min 4 < input.txt | cut -d, -f1-4
ID,y,z,p-value
1,a,b,1.2e-10
2,c,d,3e-7
3,e,f,2e-8