在AWK中读取两个文件

时间:2013-02-22 21:27:43

标签: linux awk file-handling

我有一个看起来像的文件:

1   4
2   4
3   5
4   4
5   4
6   1
7   1
8   1
9   4
10  4
12  1
13  1
14  1
15  1
16  2
19  3
20  1
21  1
26  1
28  3
24  4
29  4
30  1

第1列是序列号,第2列是值。我想计算Eg的特定范围之间的值之和:将第2列中的值与2和7之间的值相加(来自第1列)

我通过以下awk one liner实现了这一点:

awk '{if ($1 >= 2 && $1 <= 7) x += $2 } END {print x}' file_name #output is 20

问题是我想从其他文件2中读取范围:从3-9,2-6,12-20等

3 9
2 6
12 20

如何将范围从file2传递到AWK,而不是使用if语句手动键入范围。如何在AWK中读取多个文件?

3 个答案:

答案 0 :(得分:2)

您可以通过几种方式阅读多个文件。您可以在命令行上指定多个文件,在这种情况下,awk将读取每个文件一次,或者您可以使用getline从文件中读取一行。但是,在这种情况下,执行计算更昂贵的事情可能是最简单的,只需对file2中指定的每个范围读取一次file1,但不要使用awk来读取范围。类似的东西:

while read lower upper; do
awk '$1 >= lower && $1 <= upper{ x += $2 } END {print x}' \
    lower=$lower upper=$upper file1
done < file2

如果你只想阅读一次file1,你可以做一些更复杂的事情,如(未经测试):

awk 'NR==FNR{ lo[NR]=$1; hi[NR]=$2; next } 
    { for( i in lo ) if( $1 >= lo[i] && $1 <= hi[i] ) sum[i]+=$2 }
    END{ for( i in b ) print "sum of " lo[i] " to " hi[i] ": " sum[i] }' file2 file1

答案 1 :(得分:2)

你可以尝试的另一个:

awk '
  NR==FNR{
    A[$1]=$2
    next
  }
  {
    t=0
    for(i in A) if(i>=$1 && i<=$2) t+=A[i]
    print t
  }
' file rangefile

或者在一行中:

awk 'NR==FNR{A[$1]=$2; next}{t=0; for(i in A) if(i>=$1 && i<=$2) t+=A[i]; print t}' file rangefile

答案 2 :(得分:0)

这是使用awk的一种方式:

awk 'NR==FNR { a[$1]=$2; next } { for (i in a) { i+=0; if (i>=$1 && i<=$2) s+=a[i] } print s; s=0 }' file1 file2

结果:

20
18
10