首页 > 解决方案 > 如何在awk中为多个文件编写代码

问题描述

我在 AWK 中编写了一个名为 exc7 的脚本 ./exc7 file1 file2 在每个文件中都有一个矩阵

file1 :
2 6 7
10 5 4
3 8 4
file2:
-60 10
10   -60

我写的代码是:

#!/usr/bin/awk -f
{
for (i=1;i<=NF;i++)
A[NR,i]=$i
}
END{
for (i=1;i<=NR;i++){
sum += A[i,1]
}
for (i=1;i<=NF;i++)
sum2 += A[1,i]
for (i=0;i<=NF;i++)
sum3 += A[NR,i]
for (i=0;i<=NR;i++)
sum4 += A[i,NF]
print sum,sum2,sum3,sum4
if (sum==sum2 && sum==sum3 && sum==sum4) 
print "yes"
}

如果第一列和最后一列和第一行和最后一行的总和相同,它应该检查每个文件。它将打印四个总和,如果它们相等则说是。然后它应该打印所有文件中所有数字的最大总和。当我在一个文件上尝试时,就像我在 file1 上尝试时一样,它会打印:

15 15 15 15
yes

但是当我在两个或多个文件(如 file1 文件 2)上尝试时,输出为:

-35 8 -50 -31

标签: linuxawk

解决方案


你应该使用FNR代替NR并且gawk你可以使用ENDFILE代替END。但是,这应该适用于任何awk

awk 'function sumline(last,rn) {n=split(last,lr); 
                                for(i=1;i<=n;i++) rn+=lr[i]; 
                                return rn}
     function printresult(c1,r1,rn,cn) {print c1,r1,rn,cn; 
                                        print (r1==rn && c1==cn && r1==c1)?"yes":"no"}

     FNR==1{if(last)
               {rn=sumline(last);
                printresult(c1,r1,rn,cn)}
            rn=cn=c1=0;
            r1=sumline($0)}
           {c1+=$1;cn+=$NF;last=$0}
     END   {rn=sumline(last);
            printresult(c1,r1,rn,cn)}' file1 file2

15 15 15 15
yes
-50 -50 -50 -50
yes

本质上,您可以检查文件的开头并打印出前一个文件的结果,而不是检查文件的结尾。需要区别对待第一个文件。您仍然需要该END块来处理最后一个文件。

更新

根据您提出的问题,我认为您最好保持脚本不变并更改调用方式。

for file in file1 file2; 
    do echo "$file"; ./exc7 "$file";       
    done

您将为每个文件调用一次脚本,因此所有复杂性都会消失。


推荐阅读