从bash中的字符串中提取电子邮件字符串

时间:2016-09-01 11:13:03

标签: string bash

我有一个变量:$change

我试图从中提取电子邮件(找到“by”和“@”之间的字符串):

change="Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
email=$(echo $change|sed -e 's/\by\(.*\)@/\1/')

它不起作用。

6 个答案:

答案 0 :(得分:4)

您在b之前有一个转义字符,这使其成为\b。这是一个单词边界,所以你不想在这里找到它。

看到区别:

$ echo "$change" | sed -e 's/\by\(.*\)@/\1/'
#                            ^
Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'
$ echo "$change" | sed -e 's/by\(.*\)@/\1/'
#                            ^
Change 1234 on 2016/08/31  namecompany.com 'cdex abcd'
#                        ^
#                        by is not here any more

但是如果你想获得名称,只需使用.*来匹配by以外的所有内容:

$ echo "$change" | sed -e 's/.*by\(.*\)@/\1/'
 namecompany.com 'cdex abcd'

最后,如果你想要的只是by(注意尾随空格)和@之间的数据,请使用其中任何一个(-r你不必逃避被捕获的团体):

sed -e 's/.*by \(.*\)@.*/\1/'
sed -r 's/.*by (.*)@.*/\1/'

输入您的信息:

$ sed -e 's/.*by \(.*\)@.*/\1/' <<< "Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
name

答案 1 :(得分:2)

使用List<Button>您可以使用匹配重置// Get the first button in the list Button btn = myButtons[0]; // Change the caption of the buttons.... for(int x = 0; x < myButtons.Count; x++) btn.Text = "Button" + x.ToString();

 btn[i] = new Button();

或使用lookbehind:

grep -oP

答案 2 :(得分:2)

没有必要使用正则表达式匹配来使用sed,awk,grep等:

[[ $change =~ by\ ([^@]*)@ ]] && email=${BASH_REMATCH[1]}

来自手册页

  

可以使用另外的二元运算符=〜       优先级为==和!=。当它被使用时,字符串为       经营者的权利被视为延长的正常表达 -       sion并相应地匹配(如正则表达式(3))。返回值       如果字符串与模式匹配则为0,否则为1。如果       正则表达式在语法上是不正确的,有条件的       表达式的返回值为2.如果shell选项为nocasematch       启用后,将执行匹配,而不考虑情况       字母字符。可以引用该模式的任何部分       强制引用的部分匹配为字符串。托架       必须小心处理正则表达式中的表达式,       因为正常的引用字符会失去它们之间的含义       括号。如果模式存储在shell变量中,则引用       变量扩展迫使整个模式匹配       作为一个字符串。子字符串与带括号的子表达式匹配       正则表达式中保存在数组变量中       BASH_REMATCH。索引为0的BASH_REMATCH元素是       匹配整个正则表达式的字符串部分。       索引为n的BASH_REMATCH元素是。的部分       与第n个带括号的子表达式匹配的字符串。

可能令人惊讶的是,模式是在没有引号的情况下编写的,这就是为什么使用变量代替模式可能是个好主意:

regex='by ([^@]*)@'
[[ $change =~ $regex ]] && email=${BASH_REMATCH[1]}

答案 3 :(得分:1)

使用sed

sed -E 's/.* by ([^@]+).*/\1/' <<<"$change"

使用awk

awk -F@ '{sub(".* ", "", $1); print $1}' <<<"$change"

示例:

$ sed -E 's/.* by ([^@]+).*/\1/' <<<"Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
name

$ awk -F@ '{sub(".* ", "", $1); print $1}' <<<"Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
name

答案 4 :(得分:1)

awk版本,这将使用awk的内置拆分函数来分割第6个字段,使用“@”作为分隔符并将其存储在名为a的数组中。打印它以打印阵列a的第一个值。

echo $change |awk  '{ split($6,a,"@"); print a[1]}' 
name

如果您需要完整的电子邮件地址,请:

 echo $change |awk '{print $6}'
 name@company.com

答案 5 :(得分:1)

Parameter Expansion

的解决方案

首先,删除字符串by和空格

的临时变量
$ change="Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
$ tmp="${change#*by }"
$ echo "$tmp"
name@company.com 'cdex abcd'

然后,在@

之前提取字符串
$ email="${tmp%@*}"
$ echo "$email"
name

或者,提取完整的电子邮件地址

$ email="${tmp%% *}"
$ echo "$email"
name@company.com

修改

提取以逗号分隔的多个字符串:

$ change="Change 1234 on 2016/08/31 by name@company.com 'cdex abcd'"
$ email=$(echo "$change" | perl -ne 'print join(",",/(\S+)@/g)')
$ echo "$email"
name

$ change="by name@company.com asd abcd@xyz.net 123 tom@xyz asdf"
$ email=$(echo "$change" | perl -ne 'print join(",",/(\S+)@/g)')
$ echo "$email"
name,abcd,tom