仅打印第一个和最后一个匹配的模式

时间:2015-08-04 20:04:15

标签: linux bash awk

我不熟悉脚本,正在学习,我很感激所有你可以提供的帮助。我有一个包含以下数据的文件:

0252    Fri 03 Jul 2015      84082679  
0252    Fri 10 Jul 2015      81473945  
0252    Fri 17 Jul 2015      87405062  
0252    Fri 24 Jul 2015      89400396  
0253    Fri 03 Jul 2015      29038894  
0253    Fri 10 Jul 2015      29392107  
0253    Fri 17 Jul 2015      31271055  
0253    Fri 24 Jul 2015      31367348  
071    Fri 03 Jul 2015      18594024  
071    Fri 10 Jul 2015      18568430  
071    Fri 17 Jul 2015      18648903  
071    Fri 24 Jul 2015      18887643  
072    Fri 03 Jul 2015      20141235  
072    Fri 10 Jul 2015      19563727  
072    Fri 17 Jul 2015      19573266

我想要的输出如下:

0252    Fri 03 Jul 2015      84082679  
0252    Fri 24 Jul 2015      89400396  
0253    Fri 03 Jul 2015      29038894  
0253    Fri 24 Jul 2015      31367348  
071    Fri 03 Jul 2015      18594024  
071    Fri 24 Jul 2015      18887643  
072    Fri 03 Jul 2015      20141235  
072    Fri 17 Jul 2015      19573266  

输入数据中的第一列定义“组”。从每组我想要打印两行:第一行和最后一行。

我想使用awk来获得我想要的结果,因为我试图将这些信息排序为最终输出。非常感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:1)

Perl救援!

-n
  • -a逐行读取输入行
  • @F将每一行拆分为-l数组
  • print$id
  • 添加换行符
  • $keep用于保留第一列的值
  • $id会记住最后一行。当$keep更改时,会打印}{和当前行。
  • 在爱斯基摩问候语操作符{{1}}之后
  • ,一旦处理完整个文件,就会打印最后一行。

答案 1 :(得分:1)

$ awk -v h=99 'h>$3{if (last) print last;print;} {h=$3;last=$0;} END{print last}' file
0252    Fri 03 Jul 2015      84082679  
0252    Fri 24 Jul 2015      89400396  
0253    Fri 03 Jul 2015      29038894  
0253    Fri 24 Jul 2015      31367348  
071    Fri 03 Jul 2015      18594024  
071    Fri 24 Jul 2015      18887643  
072    Fri 03 Jul 2015      20141235  
072    Fri 17 Jul 2015      19573266

如何运作

该脚本使用两个变量:hlasth是前一行中第三个字段的值,last是最后一行的文本。 h的任何减少都会触发打印。

  • -v h=99

    h的初始值设置为较大的数字。

  • h>$3{if (last) print last;print;}

    如果h大于字段3,则打印前一行(如果有)和当前行。

  • h=$3;last=$0;

    更新hlast

  • END{print last}

    打印最后一行。

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed -r '1p;N;/^(\S+\s+).*\n\1/D;2s/.*\n//' file

始终打印第一行。将下一行附加到当前行,并将第一行的第一个字段与第二个字段的第一个字段进行比较。它们是相同的删除第一个并重复。否则,打印两行,但只打印第二行,如果在第2行。

答案 3 :(得分:0)

$ cat tst.awk
$1 != p1 { print p0 $0 }
{ p1 = $1; p0 = $0 ORS }
END { printf "%s", p0 }

$ awk -f tst.awk file
0252    Fri 03 Jul 2015      84082679
0252    Fri 24 Jul 2015      89400396
0253    Fri 03 Jul 2015      29038894
0253    Fri 24 Jul 2015      31367348
071    Fri 03 Jul 2015      18594024
071    Fri 24 Jul 2015      18887643
072    Fri 03 Jul 2015      20141235
072    Fri 17 Jul 2015      19573266