首页 > 解决方案 > 如何使用awk或any在命令行中为长行列表打印每组的最后一行?

问题描述

在 bash 中对许多文件使用 grep,每个文件显示几行。所以我想得到每个文件的最后一行。使用grep后,输出是这样的,

- re0_400.out:  18 F= -.36810451E+02 E0= -.36810451E+02  d E =-.133023E-01
- re0_400.out:  19 F= -.36810451E+02 E0= -.36810451E+02  d E =-.133024E-01
- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   1 F= -.18286638E+02 E0= -.18286638E+02  d E =-.182866E+02
- re0_400s.out:   2 F= -.18277347E+02 E0= -.18277347E+02  d E =0.929017E-02
- re0_400s.out:   3 F= -.18293043E+02 E0= -.18293043E+02  d E =-.640539E-02
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   1 F= -.36767212E+02 E0= -.36767212E+02  d E =-.367672E+02
- re0_450.out:   2 F= -.36750221E+02 E0= -.36750221E+02  d E =0.169913E-01
- re0_450.out:   3 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129382E-01
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01

尝试的代码是:

awk '$1=="BB" && $2>1 {print f} {f=$1}' a.txt

这是一个代码(如果满足条件则打印上一行),用于在字段满足条件时打印上一行。但就我而言,我需要在两行中比较相同的字段。

结果应该是

- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01

如何使用 awk 或 shell 中的任何命令在 bash 中获得此结果?

标签: bashawk

解决方案


您能否尝试以下操作(这里我认为您的 Input_file 具有- 您在示例中显示的哈希值,如果您没有它们,请尝试更改$2$1以下代码)。

awk '
!a[$2]++{
  b[++count]=$2
}
{
  c[$2]=$0
}
END{
  for(i=1;i<=count;i++){
    print c[b[i]]
  }
}
'   Input_file

输出如下。

- re0_400.out:  20 F= -.36797147E+02 E0= -.36797147E+02  d E =0.137473E-05
- re0_400s.out:   4 F= -.18293044E+02 E0= -.18293044E+02  d E =-.640678E-02
- re0_450.out:   4 F= -.36780151E+02 E0= -.36780151E+02  d E =-.129384E-01


说明:为上述代码添加详细说明。

awk '                         ##Starting awk program from here.
!a[$2]++{                     ##Checking condition if $2 is NOT present in array a then put $2 in array a, so this condition will make sure each filename is coming only once in arrays.
  b[++count]=$2               ##Creating an array named b whose index is variable count with increment number 1 each time and its value is $2 of current line.
}                             ##Closing BLOCK for  this condition here.
{
  c[$2]=$0                    ##Creating an array named c whose index is $2 and value is $0. Since OP needs ALWAYS the LATEST line for files so this will keep over-writing the lines values of same file names and maintain latest file name value only.
}
END{                          ##Starting END section of this awk program here.
  for(i=1;i<=count;i++){      ##Starting a for loop from i=1 to till value of count, where variable count actually having number of file names($1 or $2, $1 without hashes in your Input_file and with hashes $2).
    print c[b[i]]             ##We are printing array c whose index is b[i] which will be having exact line value.
  }                           ##Closing for loop BLOCK here.
}
'  Input_file                 ##Mentioning Input_file name here.

推荐阅读