使用grep,sed,awk(或剪切)定位要删除的字符串

时间:2019-06-05 02:04:54

标签: awk sed grep cut

我正在尝试解析一些日志,以获取每行的用户代理和帐户ID。我已经设法将用户代理和一个包含帐户ID的字符串全部放在同一行。

下一步是从其较长的字符串中提取帐户ID。我以为这很简单,因为我会知道字符串的开头,并且分隔符有/斜杠,但是用户代理也包含斜杠并且字段数量不同。

该日志文件当前看起来类似于以下示例,但是有数百到数千行要解析。幸运的是,我正在整理一个具有足够空间的分区。


USER_AGENT_PART         ACCOUNT_ID_Part_/plus/path/to/stuff/they/access

some user agent/1.3     KnownString1_32d4-56e-009f98/some/stuff/here
user/agent              KnownString1_12d3-345e-4c534/more/stuff/here
User/Agent cURL/1.5.0   KnownString2_12d34e56/stuff/things/stuff/stuff
one/User Agent/2.0      KnownString1_12d3_456e_7g8/more/random/stuff/stuff

因此,目标是保留用户代理部分和帐户ID部分,并在最后一个字符串中删除他们正在访问的内容的路径。但是我不能使用/或空格作为通用定界符,因为许多用户代理在名称中都有/以及各种空格。

此外,不同类型的用户代理比我在这里提供的这个小样本要重要得多。根据日志的不同,可以有25-50种不同的类型。因此,定位用户代理并尝试排除它似乎不值得。

看来,开始的逻辑方法是将帐户ID的一部分作为已知字符串(KnownString1或KnownString2),然后从那里获取所有内容(未知数字和带短划线的字母),直到第一个/该帐户字符串。

然后,我将删除第一个/(在帐户ID字符串中),然后删除所有内容。我希望我需要分两次通过以利用用户ID的两个已知部分。

这似乎很容易,但是我只是无法确定如何开始针对最后一个字符串。我什至没有一个很好的例子,因为我不知道如何用分隔符来定位最后一个字符串而不在用户代理部分捕获相同的分隔符。

有什么想法吗?

编辑:每行都有一个帐户ID,其中以两个常见的KnownString_中的一个开头,但随后是一系列未知的数字和破折号,直到到达第一个/。因此,在定位字符串之前,不需要搜索包含该行的行。

Edit2:我最初的帐户ID示例没有反映出字母和数字混在一起。

Edit3:由于oguz ismail和kesubagu的响应,我得以使用egrep解决此问题。看起来我正在尝试使事情变得比原来更复杂。我还意识到我需要重新审视grep,因为grep的功能远远超出了我的用途。

这是我最终使用的结果,可以一口气通过

egrep -o“。+(Kn​​ownString1 | KnownString2)_ [^ /] +”日志文件>日志文件2

2 个答案:

答案 0 :(得分:0)

您可以将isNewUseregrep选项一起使用,该选项只会输出与提供的正则表达式匹配的部分,因此您可以执行以下操作

-o

cat test | egrep -o ".+(KnownString1|KnownString2)_[_0-9-]+"文件包含您提供的输入,在这种情况下,输出为

test

答案 1 :(得分:0)

使用grep

$ grep -o '.*KnownString[^/]*' file
some user agent/1.3     KnownString1_32d4-56e-009f98
user/agent              KnownString1_12d3-345e-4c534
User/Agent cURL/1.5.0   KnownString2_12d34e56
one/User Agent/2.0      KnownString1_12d3_456e_7g8

.*匹配KnownString之前的所有内容,[^/]*匹配KnownString之后的所有内容,直到第一个/