【发布时间】:2019-10-20 13:07:50
【问题描述】:
我正在尝试解析一些日志以获取每行的用户代理和帐户 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,因为它的功能远远超出了我倾向于使用它的用途。
这是我最终使用的,一次性使用:
egrep -o ".+(KnownString1|KnownString2)_[^/]+" 日志文件 > 日志文件2
【问题讨论】:
-
第一个字段,例如
^................ KnownString...(直到KnownString...的开头是固定宽度吗? -
感谢您的回复。不,不幸的是,第一个字段长度不是固定长度。但是我能够将 kesubagu 和 oguz ismail 的响应混合成一个一次性完成的响应。