正则表达式匹配同一行上的多个字符串

时间:2017-11-02 12:38:51

标签: regex bash

我使用正则表达式按以下格式处理字段:

52.200.238.131 - - [31/Jan/2017:10:30:21 +0000] "POST /v1/articles?key=sEahu58asdasd

我想使用正则表达式提取日期和密钥。我的尝试如下:

cat Downloads/testlog.log | grep -oE '\[[0-9]{2}/[A-Za-z0-9]{3}/[0-9]{4}|key=[A-Za-z0-9]+'

我的输出在两行不同的行上打印两个匹配的字符串:

key=sEahu58nYBTJa
[31/Jan/2017

如何让它们在同一条线上打印?

key=sEahu58nYBTJa [31/Jan/2017

2 个答案:

答案 0 :(得分:3)

$ grep -oP '\d{2}/\w{3}/\d{4}|key=\w+' Downloads/testlog.log | paste -d' ' - -
31/Jan/2017 key=sEahu58asdasd

答案 1 :(得分:1)

您可以在这里使用两种方法。

第一个是使用额外的sed管道命令用空格替换换行符(参见Kenneth L's answer @superuser.com):

s='52.200.238.131 - - [31/Jan/2017:10:30:21 +0000] "POST /v1/articles?key=sEahu58asdasd'
echo $s | grep -oE '\[[0-9]{2}/[A-Za-z0-9]{3}/[0-9]{4}|key=[A-Za-z0-9]+' | sed ':a;N;$!ba;s/\n/ /g'

请参阅this online demo

但是,由于首次匹配为[31/Jan/2017 key=sEahu58asdasd,因此会输出[31/Jan/2017

如果您知道值始终存在,您也可以使用以下sed解决方案

sed -E 's#.*(\[[0-9]{2}/[A-Za-z0-9]{3}/[0-9]{4}).*(key=[A-Za-z0-9]+).*#\2 \1#'

请参阅another online demo

重点是匹配并捕获您需要的部分,并匹配您需要删除的部分,并替换为引用相应捕获捕获的值的替换后向引用\2\1基团。