【问题标题】:Pattern to get string between two specific words/characters using grep [duplicate]使用 grep 获取两个特定单词/字符之间的字符串的模式 [重复]
【发布时间】:2014-01-31 09:46:46
【问题描述】:

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

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

【问题讨论】:

  • 您能提供更多示例文本吗?

标签: regex bash grep


【解决方案1】:

使用grep -oP

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

或者使用\K 避免lookbehind

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

如果您的 grep 不支持 -P (PCRE),请使用此 sed:

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

【讨论】:

  • 谢谢。它完全符合我的需要。我不知道 -P 选项。将保存此示例以供将来使用
  • 这正是我所需要的,谢谢!
  • 如果要提取的内容分布在多行中(即可能包含一个或多个换行符),这是否有效?
  • 不,它不会跨行匹配。为此,您需要使用 grep -z
【解决方案2】:

试试awk

echo '<text> from=someuser@somedomain.com, <text>' | awk -F[=,] '{print $2}'

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

符号“(”,“)”之间的单词示例:

echo "Linux Foundation Certified Engineer (LFCE-JP)" | awk -F[\(\)] '{print $2}'
LFCE-JP

【讨论】:

  • 这个更好。
  • 我发现这更容易理解和使用。
  • 您可能需要转义一些特殊字符,例如() 并且不能直接工作。需要使用 awk -F[()]。
【解决方案3】:

一个纯粹的 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"

输出:

Result:
from=someuser@somedomain.com, <some text>
someuser@somedomain.com, <some text>
someuser@somedomain.com

注意事项:

  • ${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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2021-03-03
    • 2018-08-14
    相关资源
    最近更新 更多