如何在文本中搜索多行模式并获取最后一次出现?

时间:2013-11-12 00:20:28

标签: linux command-line awk

我需要在文件中找到pgp加密消息。它们以-----BEGIN PGP MESSAGE-----开头,以-----END PGP MESSAGE-----结尾。

到目前为止,我有这个:

$ tail -200 somefile | awk '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/'

它找到了所有的事件,但我只想要最后一个。

3 个答案:

答案 0 :(得分:2)

awk '
/-----BEGIN PGP MESSAGE-----/ {
    inBlock = 1
    block = ""
}
inBlock {
    block = block $0 ORS
    if (/-----END PGP MESSAGE-----/) {
        inBlock = 0
    }
}
END {
    printf "%s", block
}
' somefile

答案 1 :(得分:2)

您可以使用sed:

tail -200 somefile | sed -n '
  # only consider lines between BEGIN and END
  /-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/ {
    # if the beginning line, clear the hold space
    /-----BEGIN PGP MESSAGE-----/{x;d}
    # add the line to the hold space
    H
  };
  # print the hold space at the end
  ${x;p}'

这个sed注释(注释是为了解释而在实际命令中不需要),“BEGIN”和“END”之间的任何行都将被添加到保留空间,每个“BEGIN”都会清除保留空间“然后在最后打印。

编辑:

为了完整性,这里是没有注释的版本和单行(与上面相同)

tail -200 somefile | sed -n '/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/{/-----BEGIN PGP MESSAGE-----/{x;d};H};${x;p}'

答案 2 :(得分:1)

BEGIN {
    beginmsg = "-----BEGIN PGP MESSAGE-----"
    endmsg = "-----END PGP MESSAGE-----"
}

$0 ~ beginmsg {
    block = ""
}

beginmsg,endmsg {
    block = block $0 ORS
}

END {
    printf "%s", block
}