使用来自两个文件的信息循环

时间:2016-10-03 22:22:55

标签: unix for-loop awk while-loop

我有两个文件,如下:
file1

name1
name2
name3
name4
name5
name6
name7
name8
name9
name10
name11
name12
name13
name14
name15

file2

name1   name1   3
name2   name1   4
name3   name1   2
name4   name1   1
name5   name1   5
name6   name1   3
name7   name1   7
name8   name1   6
name9   name1   7
name10  name1   5
name11  name1   9
name12  name1   5 
name13  name1   7
name14  name1   1
name15  name1   3
name1   name2   1
name2   name2   8
name3   name2   5
...

我想要做的是一个循环,它获取file1中的名称,并计算当catte的名称出现在file2的第一列时,file2的colum 3的前10个最高值的平均值,当列1时进行解释和2相等。

期望的输出:
name1 5.8 name2 avg_value_top10 name3 avg_value_top10

将awk用于一个名称将是这样的:

awk '$1!="name1" && $2=="name1" {print}' file2 | sort -rn -k3 | head |  awk '{total+=$3} END {print $2,total/NR}' >> out

任何帮助?
谢谢!

3 个答案:

答案 0 :(得分:2)

我建议:

awk '
    NR == FNR {names[$1]; next}
    $1 == $2 || !($2 in names) || count[$2] == 10 {next}
    {sum[$2] += $3; count[$2]++}
    END {
        for (name in sum)
            print name, sum[name]/count[name]
    }
' file1 file2

根据您的样本数据,输出

name1 0.01339
name2 0.12955

答案 1 :(得分:1)

也许是这样的:

awk 'FNR==NR {total[$1]=0; next} 
     $1==$2{next} 
       {c[$1]++; total[$1]+=$3} 
     END{ for (n in total)if (c[n]){print n, total[n]/c[n]}}' f1.txt f2.txt

如果您想要前10名,请通过awk管道运行sort | head的结果,如下所示:

awk 'FNR==NR {total[$1]=0; next} 
     $1==$2{next} 
       { c[$1]++; total[$1]+=$3} 
     END{ for (n in total){ if (c[n]) print n, total[n]/c[n]}}' f1.txt f2.txt | sort -k2rn | head

为您的示例打印:

name3 0.13525
name7 0.0237
name4 0.0235
name8 0.019
name10 0.0151
name12 0.0115
name11 0.0091
name2 0.0091
name13 0.0077
name9 0.007

答案 2 :(得分:1)

此awk脚本计算file2的列3或字段3中最高10个值的平均值,不包括{{1>} <{>>字段2 中$1==$2的值{{1} }}。在问题中,您希望名称或关键字出现在file1的字段1中,但在这种情况下,file2的平均值为1,因为字段1中只有两个记录name1 name1的第一个被排除在外,只留下1个用于计算。如果您坚持要求关键字来自字段1,请将所有对file2的引用更改为$2

$1用于在第三个字段上对sort进行排序,以获得平均值的最高值。

file2

执行命令

$ cat script.awk
NR==FNR {                            # read in file1
    a[$1]
    next
} 
($2 in a) && $1 != $2 && b[$2]<10 {  # the conditions
    b[$2]++                          # count of seen values
    a[$2]+=$3                        # summing the values
} 
END {                                # after getting the data
for(i in b)                          # for all good values
    print i, a[i]/b[i]               # calculate and print the average
}