首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从文件中提取每个对象的最大值。

从文件中提取每个对象的最大值。
EN

Unix & Linux用户
提问于 2021-04-09 11:05:48
回答 3查看 161关注 0票数 0

我需要从bash中的CentOS系统中的一个文件中提取一些值。在myfile.txt中,我有一个名为Info_region的对象列表,其中每个对象都使用代码进行标识(例如。BARD1_region_005BIRC2_region_002等)此外,还有其他一些列,其中报告了一些数值变量。相同的对象(相同的代码名)可以在我的文件中重复多次。我也有一个文件,其中包含一个完整的列表,所有的对象代码都没有重复。我希望获得一个output.txt文件,其中每个对象(代码名)只报告一次,就像在list-file.txt中一样,我想将与myfile.txt中的代码名关联的最大可能值关联到这个文件中。

myfile.txt:(列由tab分隔)

代码语言:javascript
复制
Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
BIRC2_region_001    1   6   7   0   1   2
BIRC2_region_001    1   7   8   0   1   2
BIRC2_region_001    0   2   2   0   0   0
BIRC2_region_001    0   12  12  0   1   1
BIRC2_region_001    1   10  11  -1  1   1
BIRC2_region_001    1   2   3   0   1   2
BIRC2_region_001    1   0   1   0   1   2
BIRC2_region_001    1   6   7   0   1   2
BIRC2_region_002    0   0   0   0   1   1
BIRC2_region_002    1   0   0   -1  0.5 0.5
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_004    1   0   1   0   0.5 1.5
UHRF1_region_004    0   0   0   1   1   2
UHRF1_region_005    0   3   3   1   1   2
UHRF1_region_005    1   0   0   -1  1   1

文件-list.txt:

代码语言:javascript
复制
Info_region
BARD1_region_005
BARD1_region_006
BIRC2_region_001
BIRC2_region_002
BIRC2_region_003
BIRC2_region_004
UHRF1_region_004
UHRF1_region_005

output.txt:

代码语言:javascript
复制
Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
BIRC2_region_001    1   12  12  0   1   2
BIRC2_region_002    1   0   0   0   1   1
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
UHRF1_region_004    1   0   1   1   1   2
UHRF1_region_005    1   3   3   1   1   2

有人能帮帮我吗?谢谢!

EN

回答 3

Unix & Linux用户

回答已采纳

发布于 2021-04-09 11:38:50

假设数据位于名为file的文件中,并且它是在第一列上排序的,那么GNU datamash实用程序可以在数据文件上一次性完成这一任务:

代码语言:javascript
复制
datamash -H -W -g 1 max 2-7 

这指示实用程序使用空格分隔列(-W;如果您的列是真正以制表符分隔的,则删除此列),数据的第一行包含标题(-H),按第一列(-g 1)分组,并计算第二列到第七列的最大值。

鉴于问题中的数据,结果如下:

代码语言:javascript
复制
GroupBy(Info_region)    max(Lig_score)  max(Lig_prevista)       max(Lig_prevista_+1)    max(Int_score)     max(Expo_score) max(Protac_score)
BARD1_region_005        0       3       3       0       1       1
BARD1_region_006        0       1       1       0       1       1
BIRC2_region_001        1       12      12      0       1       2
BIRC2_region_002        1       0       0       0       1       1
BIRC2_region_003        0       0       0       0       1       1
BIRC2_region_004        0       1       1       0       1       1
UHRF1_region_004        1       0       1       1       1       2
UHRF1_region_005        1       3       3       1       1       2

您还可以使用--header-in代替-H来获得少头输出,然后从原始数据文件中获取报头:

代码语言:javascript
复制
{ head -n 1 file; datamash --header-in -W -g 1 max 2-7 output

在这里,我还将结果写入一些名为output的新输出文件。

使用awk并假定制表符分隔字段:

代码语言:javascript
复制
awk -F '\t' '
    BEGIN { OFS = FS }
    NR == 1 { print; next }
    {
        n[$1] = 1
        for (i = 2; i <= NF; ++i)
            a[$1,i] = (a[$1,i] == "" || $i > a[$1,i] ? $i : a[$1,i])
    }
    END { 
        nf = NF
        for (j in n) {
            $0 = j
            for (i = 2; i <= nf; ++i)
                $i = a[$1,i]
            print
         }
     }' file

这将计算每个组的每个列中的最大值。这些数字存储在a数组中,而n数组只将组名作为键保存。

票数 5
EN

Unix & Linux用户

发布于 2021-04-09 12:04:01

我假设您实际上不想在bash (也不应该)这样做,而是愿意使用其他工具。下面是一种GNUawk方法:

代码语言:javascript
复制
$ gawk -vOFS="\t" -F'\t' \
    '{ 
        if(NR==1){print; } 
        else{ 
            for(i=2;i<=NF;i++){ 
                if($i > a[$1][i] || ! a[$1][i]){a[$1][i]=$i}
           }
        } 
     }
     END{ 
        for (region in a){ 
            printf "%s", region; 
            for(i=2;i<=NF;i++){ 
                printf "%s%s", OFS,a[region][i]
            } 
            printf "\n";  
        } 
     }' myfile.txt 
Info_region Lig_score   Lig_prevista    Lig_prevista_+1 Int_score   Expo_score  Protac_score
BIRC2_region_001    1   12  12  0   1   2
BIRC2_region_002    1   0   0   -1  1   1
BIRC2_region_003    0   0   0   0   1   1
BIRC2_region_004    0   1   1   0   1   1
BARD1_region_005    0   3   3   0   1   1
BARD1_region_006    0   1   1   0   1   1
UHRF1_region_004    1   0   1   1   1   2
UHRF1_region_005    1   3   3   1   1   2
票数 2
EN

Unix & Linux用户

发布于 2021-04-09 23:27:02

这是一种既不使用真正的多维数组也不使用模拟多维数组的方法。相反,我们用相同的键存储块。

代码语言:javascript
复制
awk '
BEGIN { OFS = FS = "\t" }
NR==1 { print; next }
{
  obj = $1; $1=""; sub(FS, "")
  a[obj] = a[obj] $0 FS
}
END {
  nf0 = NF
  for (obj in a) {
    $1 = obj
    nf = split(a[obj], f)
    for (i=1; i<=nf0; i++) {
      $(i+1) = f[i]
      for (j=0; j $(i+1) ) $(i+1) = f[idx]
      }
    }
    print
  }
}
' myfile.txt
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/644271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档