使用grep在两个特定单词/字符之间获取字符串的模式

Shi*_*ker 12 regex bash grep

我需要从像这样的字符串中提取电子邮件地址(我正在创建一个日志解析器): <some text> from=someuser@somedomain.com, <some text>

egrep(或grep -Eo).所以字符串只需要在"from="和之间拉出",",因为日志的其他部分也包含电子邮件地址,比如to=etc

anu*_*ava 27

使用grep -oP:

s='<some text> from=someuser@somedomain.com, <some text>'
grep -oP '(?<=from=).*?(?=,)' <<< "$s"
someuser@somedomain.com
Run Code Online (Sandbox Code Playgroud)

或者lookbehind通过使用避免\K:

grep -oP 'from=\K.*?(?=,)' <<< "$s"
someuser@somedomain.com
Run Code Online (Sandbox Code Playgroud)

万一你grep不支持-P(PCRE)使用这个sed:

sed 's/.*from=\(.*\),.*/\1/' <<< "$s"
someuser@somedomain.com
Run Code Online (Sandbox Code Playgroud)


mic*_*ael 14

一个纯粹的 bash 解决方案,需要两个步骤来分别去除前缀和后缀(但可能运行得更快,因为没有子进程):

#!/bin/bash
orig='from=someuser@somedomain.com, <some text>'
one=${orig#*from=}
two=${one%,*}

printf "Result:\n"
printf "$orig\n"
printf "$one\n"
printf "$two\n"
Run Code Online (Sandbox Code Playgroud)

输出:

Result:
from=someuser@somedomain.com, <some text>
someuser@somedomain.com, <some text>
someuser@somedomain.com
Run Code Online (Sandbox Code Playgroud)

笔记:

  • ${var#*pattern}使用#带从开始$var直至pattern
  • ${var%pattern*}使用%从结尾的条带$var,直到pattern
  • 类似的可以用${var/pattern/replace}(并replace留空)来完成,但它更棘手,因为不支持完整的正则表达式(即,不能使用^或“$”),所以你不能做(例如)/^from=//,但你可以做第一步${var/*from=/},然后在第二步,做${var/,*/}(当然取决于你的数据)。
  • 另见:http : //www.tldp.org/LDP/abs/html/parameter-substitution.html


Shi*_*dim 12

尝试 awk

echo '<text> from=someuser@somedomain.com, <text>' | awk -F[=,] '{print $2}'
Run Code Online (Sandbox Code Playgroud)

$2根据其位置,这里可以是不同的数字.

  • 我发现这更容易理解和使用。 (3认同)