【问题标题】:Reading two files in AWK在 AWK 中读取两个文件
【发布时间】:2013-02-08 14:52:41
【问题描述】:

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

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 中读取多个文件?

【问题讨论】:

标签: linux awk file-handling


【解决方案1】:

您可以通过几种方式读取多个文件。您可以在命令行上指定多个文件,在这种情况下 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

【讨论】:

  • 第一个程序没有给出正确的输出,但第二个正在给出。
【解决方案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

【讨论】:

  • A[$1]=$2部分我没看懂
  • NR==FNR 的唯一时间是在读取第一个文件时。在此期间,该文件的值被放入数组“A”中,索引为 $1,值为 $2 (A[$1]=$2)。该数组用于第二部分,当读取范围文件时,对于范围文件中的每个范围,数组 A 将被枚举,因此 i 将包含 $1A[i] 将包含 $2第一个文件的行..
【解决方案3】:

这是使用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

【讨论】:

  • 我不明白 a[$1]=$2 部分。
  • @gthmgeeky:字段一 ($1) 被添加到一个值为字段二 ($2) 的数组(称为 a)中。 HTH。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 2013-09-21
  • 2019-04-13
相关资源
最近更新 更多