用于循环和执行数学运算的Awk脚本

用于循环和执行数学运算的Awk脚本,awk,Awk,我使用bash和awk脚本从文本文件中提取数据。 但是,它对于大型数据集来说速度太慢,并且不能完美地工作。我相信在一个awk命令中编写所有bash循环是可能的,我请求某人帮助我完成这项工作 cat dummy_list AAA AAAA AAAAA cat dummy_table 13 19 AAA 69 96 "ID-999" 34 23 42 AAA 12 19 "ID-999" 64 53

我使用bash和awk脚本从文本文件中提取数据。
但是,它对于大型数据集来说速度太慢,并且不能完美地工作。我相信在一个awk命令中编写所有bash循环是可能的,我请求某人帮助我完成这项工作

cat dummy_list 
    AAA
    AAAA
    AAAAA

cat dummy_table
    13   19   AAA   69   96   "ID-999"   34
    23   42   AAA   12   19   "ID-999"   64
    53   79   AAA   43   58   "ID-482"   36
    13   43   AAA   12   15   "ID-492"   75
    23   90   AAA   45   87   "ID-492"   34
    12   41   AAAA   76   79   "ID-923"   23
    19   58   AAAA   15   87   "ID-923"   75
    10   40   AAAA   18   82   "ID-482"   23
    11   18   AAAA   18   82   "ID-482"   52
    15   19   AAAA   18   82   "ID-482"   62
    59   69   AAAA   10   18   "ID-482"   83
    78   89   AAAA   32   41   "ID-983"   24
    23   53   AAAAA  78   99   "ID-916"   82
我想从这张桌子上得到什么:

  • 对于每个虚拟列表项(
    AAA
    AAAA
    aaaaaaa
    ),提取提到ID范围的不同次数(我指的是唯一列4+5+6(如
    69 96“ID-999”
    )。有重复的ID(如
    18 82“ID-482”
    ),我必须丢弃它们。
    我的脚本如下所示:

    while read a; do  
        awk -v VAR="$a" '($3==VAR) {print $4"\t"$5"\t"$6}' dummy_table |   
        sort -u |   
        cut -f 3 |  
        sort |   
        uniq -c |   
        awk '{print $1}' |   
        tr '\n' ' ' |   
       awk -v VAR="$a" '{print VAR"\t"$0}'   
    done < dummy_list
    
    AAA     1 2 2 
    AAAA    2 2 1 
    AAAAA   1 
    
    while read a ; do  
        ID_TIMES=$(awk -v VAR="$a" '($3==VAR) {print $6}' dummy_table | 
           sort -u | 
            wc -l) && 
        awk -v  VAR="$a" '($3==VAR) {print $6}' dummy_table | 
        sort | 
        uniq -c | 
        awk -v VAR="$ID_TIMES" '{sum+=$1} END {print sum/VAR}' 
    done < dummy_list
    
    AAA   1.666  
    AAAA  2.333
    AAAAA 1
    
  • 对于每个虚拟列表项,提取ID范围并计算列之间的比例。 例如:
    用于AAA的ID-999:
    范围1=总和$5-$4(96-69)+$5-$4(19-12)
    范围2=总额7美元(34+64)
    然后RANGE2*100/RANGE1=288

    对于这样的输出:

    AAA 288 240 242 
    ....
    AAAAA 390
    
    我无法自己编写这样的脚本,因为我被两个变量$RANGE1和$RANGE2卡住了。
    如果可能的话,最好在这一步中也放弃重复的范围,如
    18 82“ID-482”

  • 我相信所有这些操作都可以通过一个
    awk
    命令来计算,我对我的脚本感到绝望。我真的希望有人能在这次手术中帮助我

    你可以试试这个

    文件a.awk:

    BEGIN {
    
        # read list of items
    
        while ( ( getline < "dummy_list" ) > 0 )
        {
            items[$1] = 0    
        }
    }
    
    {
        # calculate ammountof uniqur ids
    
        key = $3 SUBSEP $6
    
        if ( ! ( key in ids ) && ( $3 in items ) )
        {
            unique_ids[$3] += 1 
        }
    
    
        # calculate ammount of duplication
    
        ids [$3,$6] += 1 
    
    
        # calculate range parameters 
    
        range1 [$3,$6] += $5 - $4
        range2 [$3,$6] += $7 
    }
    
    END {
    
        for ( item in items )
        {
            print "--- item = " item " ---\n"
    
            for ( key in ids )
            {
                split ( key, s, SUBSEP );
    
                if ( s[1] != item ) continue;    
    
                range = range2[key] * 100 / range1[key] 
    
                average[item] += float ( ids[key] ) / unique_ids[item];
    
                print "id = " s[2] "\tammount of dup = " ids[key] "  range = " int ( range )
            }    
    
            print "\naverage = " average[item] "\n"
        }
    }
    
    有那么一刻,我不明白你是怎么知道的 对于“ID-482”和问题中的AAA项#3

    你确定你关于问题3的例子是正确的吗?

    你可以试试这个

    文件a.awk:

    BEGIN {
    
        # read list of items
    
        while ( ( getline < "dummy_list" ) > 0 )
        {
            items[$1] = 0    
        }
    }
    
    {
        # calculate ammountof uniqur ids
    
        key = $3 SUBSEP $6
    
        if ( ! ( key in ids ) && ( $3 in items ) )
        {
            unique_ids[$3] += 1 
        }
    
    
        # calculate ammount of duplication
    
        ids [$3,$6] += 1 
    
    
        # calculate range parameters 
    
        range1 [$3,$6] += $5 - $4
        range2 [$3,$6] += $7 
    }
    
    END {
    
        for ( item in items )
        {
            print "--- item = " item " ---\n"
    
            for ( key in ids )
            {
                split ( key, s, SUBSEP );
    
                if ( s[1] != item ) continue;    
    
                range = range2[key] * 100 / range1[key] 
    
                average[item] += float ( ids[key] ) / unique_ids[item];
    
                print "id = " s[2] "\tammount of dup = " ids[key] "  range = " int ( range )
            }    
    
            print "\naverage = " average[item] "\n"
        }
    }
    
    有那么一刻,我不明白你是怎么知道的 对于“ID-482”和问题中的AAA项#3


    你确定你关于问题#3的例子是正确的吗?

    只是部分答案,但这是你第一个问题的一行解决方案:

      awk -F'   ' '{group[$3]++;ind[$6]++};{count[$3][$6]+=1}; END{for (i in group){for (j in ind) if(count[i][j] > 0) print i, j, count[i][j]}}' dummy_variable.txt 
    
    输出:

    AAA "ID-482" 1  
    AAA "ID-999" 2  
    AAA "ID-492" 2    
    AAAA "ID-923" 2  
    AAAA "ID-482" 4  
    AAAA "ID-983" 1  
    AAAAA "ID-916" 1
    

    然后,使用此输出计算第二个问题的答案是相当麻烦的。

    仅部分答案,但这里是第一个问题的一行解决方案:

      awk -F'   ' '{group[$3]++;ind[$6]++};{count[$3][$6]+=1}; END{for (i in group){for (j in ind) if(count[i][j] > 0) print i, j, count[i][j]}}' dummy_variable.txt 
    
    输出:

    AAA "ID-482" 1  
    AAA "ID-999" 2  
    AAA "ID-492" 2    
    AAAA "ID-923" 2  
    AAAA "ID-482" 4  
    AAAA "ID-983" 1  
    AAAAA "ID-916" 1
    

    然后,使用此输出计算第二个问题的答案相当麻烦。

    我的错误-必须手动计算百分比,我编辑了我的问题。我的错误-必须手动计算百分比,我编辑了我的问题。你考虑过使用关系数据库吗?这就是我需要所有这些数据提取的原因。你考虑过使用关系数据库吗?这就是我需要所有这些数据提取的原因。
    ;do NUMBER=$(grep-w$a输出| awk'{print$2}'| sort-u | wc-l)&&awk-v ID=“$a”-v NUMBER=“$NUMBER””($1==ID){sum+=$3}结束{print sum/NUMBER}输出;完成
    我在一个awk命令中写入所有内容并将其与上一步连接时遇到问题;do NUMBER=$(grep-w$a输出| awk'{print$2}'| sort-u | wc-l)&&awk-v ID=“$a”-v NUMBER=“$NUMBER””($1==ID){sum+=$3}结束{print sum/NUMBER}输出;完成我在一个awk命令中编写所有内容并将其与上一步连接时遇到问题。