0

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

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 列是值。我想计算特定范围之间的值之和,例如:将 column2 中介于 2 和 7 之间的值相加(来自 column1)

我通过以下 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 中读取多个文件?

4

3 回答 3

3

您可以尝试另一个:

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
于 2013-02-22T21:46:09.380 回答
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
于 2013-02-22T21:32:20.310 回答
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
于 2013-02-23T12:10:58.097 回答