我想知道是否有可能从非格式化字符串中使用grep -P
(linux bash)命名正则表达式?好..来自任何字符串
例如:
John Smith www.website.com john@website.com jan-01-2001
捕获为
$name
$website
$email
$date
但似乎我无法从输出中传递任何变量?
echo "www.website.com" | grep -Po '^(www\.)?(?<domain>.+)$' | echo $domain
没有输出
答案 0 :(得分:4)
没有。 grep是一个过程。你在谈论从孩子到父母的环境传播。这是被禁止的。
相反,你可以做
DATA=($your_line)
然后来回name=DATA[0]
。
或使用awk的其他方式:
eval "`echo $your_line | awk '
function escape(s)
{
gsub(/'\''/,"'\''\"'\''\"'\''", s);
s = "'\''"s"'\''";
return s;
}
{
print "name="escape($1);
print "family_name="escape($2);
print "website="escape($3);
print "email="escape($4);
print "date="escape($5);
}'`"
这里的意思是通过stdout传播信息并在父环境中评估它。
请注意,在这里,escape函数将正确地转义任何字符串,这样就不会错误地解释任何字符串(比如引号的邪恶)。
以下是我的杰西的输出:
name='John'
family_name='Smith'
website='www.website.com'
email='john@website.com'
date='jan-01-2001'
如果姓氏为O'Reilly
,则评估结果仍然正确:
name='John'
family_name='O'"'"'Reilly'
website='www.website.com'
email='john@website.com'
date='jan-01-2001'
答案 1 :(得分:3)
Grep是一个独立的命令行实用程序;它不会在bash中运行。因此即使它想要也无法创建bash变量。
但是,bash内置了正则表达式匹配器。它不是perl兼容的正则表达式匹配器,因此它不实现命名捕获。 (确切地说,它与Posix扩展正则表达式匹配,与grep -E
相同。)但它确实实现了编号捕获。
您可以使用=~
复合命令语法中的[[ ... ]]
运算符进行正则表达式匹配。如果正则表达式匹配,则表达式成功,并将捕获插入到数组变量BASH_REMATCH
中。 ${BASH_REMATCH[0]}
将是整个匹配的子字符串,其余元素(从${BASH_REMATCH[1]}
开始)将按顺序进行单独捕获。
例如:
$ url=www.example.com
$ [[ $url =~ ^(www\.)?(.*) ]]
$ echo "${BASH_REMATCH[1]}"
www.
$ echo "${BASH_REMATCH[2]}"
example.com