grep 的 -o 选项可以只输出匹配的部分。但是有时候,我们只想要匹配的部分中一部分结果。
比如我们要找出ping持续输出结果中,响应最长的时间
64 bytes from 192.168.1.20: seq=3 ttl=64 time=2013.152 ms
64 bytes from 192.168.1.20: seq=5 ttl=64 time=11.641 ms
我们匹配time=%d,但只想输出%d,然后使用sort进行排序。
此时,用到了正则表达式中的 lookbehind / lookhead assertion,它们要求某个位置出现某个pattern。但是这个pattern不在匹配结果中。
Lookaround | Name | What it Does |
---|---|---|
(?=foo) | Lookahead | Asserts that what immediately FOLLOWS the current position in the string is foo |
(?<=foo) | Lookbehind | Asserts that what immediately PRECEDES the current position in the string is foo |
(?!foo) | Negative Lookahead | Asserts that what immediately FOLLOWS the current position in the string is NOT foo |
(?<!foo) | Negative Lookbehind | Asserts that what immediately PRECEDES the current position in the string is NOT foo |
lookhead是pattern后面必须有这个pattern(提前取这个pattern来比较)。
lookbehind是pattern后面必须有这个pattern(返回去取来比较)。
negative是取反,表示不能有。
grep使用上面的语法,需要使用-P选项,使用Perl regexp。
比如匹配time=%d,是%d前面必须要有某个pattern,因此使用lookbehind。语法如下:
grep -oP "(?<=time=)[0-9]+" a.log
另外还有一个Non-Capturing Groups
(?:)
但是这个也是匹配的一部分,不是这个应用场景,它只表示不存储起来用来back-references
"Non-capturing" doesn't mean that the group isn't part of the match; it means that the group's value isn't saved for use in back-references.
https://stackoverflow.com/questions/15136366/how-to-use-non-capturing-groups-in-grep
https://stackoverflow.com/questions/3926451/how-to-match-but-not-capture-part-of-a-regex