管道grep和使用正则表达式

Sky*_*969 9 regex bash

基本上我想要做的是解析文件中的行并返回用户名.用户名总是包含在<和>中,所以我想使用正则表达式来匹配(包括)<和之后的所有内容(包括)之后的eveything,然后反转我的匹配.我明白grep -vE应该能够做到这一点.

到目前为止,我的脚本看起来像这样:

#!/bin/bash
while read line; do
        echo $line | grep -vE '(.*<)|(>.*)'
done < test_log
Run Code Online (Sandbox Code Playgroud)

test_log包含以下内容:

Mar  1 09:28:08 (IP redacted) dovecot: pop3-login: Login: user=<emcjannet>, method=PLAIN, rip=(IP redacted), lip=(IP redacted)
Mar  1 09:27:53 (IP redacted) dovecot: pop3-login: Login: user=<dprotzak>, method=PLAIN, rip=(IP redacted), lip=(IP redacted)
Mar  1 09:28:28 (IP redacted) dovecot: imap-login: Login: user=<gconnie>, method=PLAIN, rip=(IP redacted), lip=(IP redacted), TLS
Mar  1 09:27:25 (IP redacted) dovecot: imap-login: Login: user=<gconnie>, method=PLAIN, rip=(IP redacted), lip=(IP redacted), TLS
Run Code Online (Sandbox Code Playgroud)

但是,在运行我的脚本时,没有返回任何内容,尽管当我使用反向匹配测试regex之类的正则表达式时它完全符合我的要求.我究竟做错了什么?

Ken*_*ent 19

尝试这个grep行:

grep -Po "(?<=<)[^>]*"
Run Code Online (Sandbox Code Playgroud)

或更安全:

grep -Po "(?<=user=<)[^>]*"
Run Code Online (Sandbox Code Playgroud)

编辑

简短的解释

-P perl-regex
-o only matching
you can get above info from man page
(?<=foo)bar look-behind assertion. matches bar, only if bar is following foo.
[^>]* any not > characters.
Run Code Online (Sandbox Code Playgroud)


Vic*_*kyi 6

其实,我喜欢@肯特的答案也和它是正确的,但有时很难记住像开关“-Po”“grep的”实用工具。通常,如果您不记得确切的标志,您可以要求 grep 实用程序以下列方式刷新您的记忆:

$ grep --help | grep regex
  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN for matching
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,还有另一个可能的选项,比如"-E"