使用awk处理两个文件


9

我读的比较使用Unix和awk中两个文件。真的很有趣。我已经阅读并测试了它,但是我无法完全理解它并在其他情况下使用它。

我有两个文件。file1有一个字段,另一个有16个字段。我想阅读file1的元素,并将它们与的第3个字段进行比较file2。如果每个元素都匹配,我将中的字段5的值相加file2。举个例子:

文件1

1
2
3

文件2

2 2 2 1 2
3 6 1 2 4 
4 1 1 2 3
6 3 3 3 4 

对于元素1,file1我想在字段file23的值为1的字段5中添加值。并对元素2和3中的元素执行相同的操作file1。1的输出为(3 + 4 = 7),2的输出为2,3的输出为4。

我不知道如何用awk编写它。

Answers:


20

这是一种方法。我已将其编写为awk脚本,因此可以添加注释:

#!/usr/local/bin/awk -f

{
    ## FNR is the line number of the current file, NR is the number of 
    ## lines that have been processed. If you only give one file to
    ## awk, FNR will always equal NR. If you give more than one file,
    ## FNR will go back to 1 when the next file is reached but NR
    ## will continue incrementing. Therefore, NR == FNR only while
    ## the first file is being processed.
    if(NR == FNR){
      ## If this is the first file, save the values of $1
      ## in the array n.
      n[$1] = 0
    }
    ## If we have moved on to the 2nd file
    else{
      ## If the 3rd field of the second file exists in
      ## the first file.
      if($3 in n){
        ## Add the value of the 5th field to the corresponding value
        ## of the n array.
        n[$3]+=$5
      }
    }
}
## The END{} block is executed after all files have been processed.
## This is useful since you may have more than one line whose 3rd
## field was specified in the first file so you don't want to print
## as you process the files.
END{
    ## For each element in the n array
    for (i in n){
    ## print the element itself and then its value
    print i,":",n[i];
    }
}

您可以将其另存为文件,使其可执行并按以下方式运行:

$ chmod a+x foo.awk
$ ./foo.awk file1 file2
1 : 7
2 : 2
3 : 4

或者,您可以将其浓缩为单线:

awk '
     (NR == FNR){n[$1] = 0; next}
     {if($3 in n){n[$3]+=$5}}
     END{for (i in n){print i,":",n[i]} }' file1 file2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.