使用awk添加多个文件的内容

使用awk添加多个文件的内容

假设我有一些名为file1, file2, file3, ... 的文件具有以下格式

文件1

blah blah blah
[PATTERN0]
a10
a20
a30
[PATTERN1]
a11
a21
a31
[PATTERN3]
a13
a13
a33

文件2

blah blah blah
[PATTERN0]
b10
b20
b30
[PATTERN1]
b11
b21
b31
[PATTERN3]
b13
b13
b33

我想要做的是最终得到一个文件,其中包含特定模式(即 PATTERN0)之后的所有文件的每个单独条目的总和。例如该文件应该有

a10+b10
a20+b20
a30+b30

到目前为止,我只能使用 rrad 和打印值

awk '/PATTERN0/ {for(i=1; i<=3; i++) {getline;print $1}}' file*

知道怎么做吗?

答案1

对于awk,假设您始终有至少两个文件,所有文件在[PATTERN0]和之间具有相同的行数[PATTERN1],并且所述行实际上是数字:

awk '
    BEGIN {
        # discard the garbage before [PATTERN0]
        for (i = 1; i < ARGC; i++) {
            do      
                getline str <ARGV[i]
            while (str !~ /\[PATTERN0\]/)
        }

        # read sum from first file, then add numbers in turn from the other files
        while ((getline sum <ARGV[1]) && sum !~ /\[PATTERN1\]/) {
            for (i = 2; i < ARGC; i++) {
                getline nr <ARGV[i]
                sum += nr
            }
            print sum
        }
    }' file1 file2 file3 ...

答案2

Paste + awk 的组合给出了很好的结果:

$ paste -d"+" file1 file2 |awk -F"[+]" '/PATTERN/{print $1;next}1'

我调用 awk 以避免出现[PATTERN0]+[PATTERN0]- 您可以将其删除,或者如果您根本不想[PATTERN]打印,请将最后一个 awk 更改为
...|awk -F"[+]" '/PATTERN/{next}1

测试:

$ paste -d"+" <(echo "$a") <(echo "$b") |awk -F"[+]" '/PATTERN/{next}1'
a10+b10
a20+b20
a30+b30
a11+b11
a21+b21
a31+b31
a13+b13
a13+b13
a33+b33

这里还有一个简单的 awk 解决方案:

$ awk -v RS="[PATTERN[0-9]+]" '{for (i=1;i<=NF;i++) (NR==FNR)?a[RT][i]=$i:a[RT][i]=a[RT][i] "+" $i} \
END{for (k in a) for (l in a[k]) print a[k][l]}' <(echo "$a") <(echo "$b")

PS:上面的 awk 通过删除 .awk 成为一行\。为了便于阅读,这里将其分为两行。

这个 awk 的陷阱是,在 END 部分,打印是正确的,但由于 awk 使用此 for 方法打印数组的方式,打印是随机的 PATTERN 顺序(即[PATTERN3]数据可能首先打印而不是)。[PATTERN0]

相关内容