2010-09-04 67 views
2

我发现这个,但它假定单词是空格分开的。bash脚本提取正则表达式模式的所有匹配

result="abcdefADDNAME25abcdefgHELLOabcdefgADDNAME25abcdefgHELLOabcdefg" 

for word in $result 
do 
    if echo $word | grep -qi '(ADDNAME\d\d.*HELLO)' 
    then 
     match="$match $word" 
    fi 
done 

POST EDITED

重新命名为清楚:

data="abcdefADDNAME25abcdefgHELLOabcdefgADDNAME25abcdefgHELLOabcdefg" 
for word in $data 
do 
    if echo $word | grep -qi '(ADDNAME\d\d.*HELLO)' 
    then 
     match="$match $word" 
    fi 
done 
echo $match 

原始留下这样的评论询问result继续意义。

+0

我很难理解你的脚本。 '$ world'应该与'$ result'相对应吗?然而,你的模式中没有任何东西可以匹配'$ world'中的任何东西。你能否展示一个你想要匹配的字符串和你想要使用的模式的更好的例子? – 2010-09-04 18:31:12

+0

我编辑了这篇文章,但没有正确说明。 – 2010-09-04 19:55:07

+0

目前还不清楚你在找什么结果。现在'在$ result中输入'只能看到一个“单词”(包含在$ result中的完整字符串)你想'$ match'在结尾包含什么? – 2010-09-04 20:15:28

回答

4

编辑:答案编辑问题:

for string in "$(echo $result | grep -Po "ADDNAME[0-9]{2}.*?HELLO")" 
do 
    match="${match:+$match }$string" 
done 

原始回答:

如果您使用Bash版本3.2或更高版本,则可以使用其正则表达式匹配。

string="string to search 99 with 88 some 42 numbers" 
pattern="[0-9]{2}" 
for word in $string 
do 
    [[ $word =~ $pattern ]] 
    if [[ ${BASH_REMATCH[0]} ]] 
    then 
     match="${match:+match }${BASH_REMATCH[0]}" 
    fi 
done 

结果将是“99 88 42”。

+0

我编辑我的帖子:我的字符串没有空格,因此它会不工作 – 2010-09-04 20:04:00

+0

@bobby:看我的编辑。 – 2010-09-04 20:42:24

+0

为什么不缩短它:...做; [[$ word =〜$ pattern]] && match =“$ {match:+ match} $ {BASH_REMATCH [0]}”;完成 – user377178 2013-10-14 11:20:22

2

使用grep -o

-o,--only匹配只显示一行匹配模式的一部分

+0

7年后,这正是我所需要的 – adg 2017-08-20 19:28:58

0

不是很优雅 - 有因为贪婪匹配的问题 - 但是这或多或少作品:

data="abcdefADDNAME25abcdefgHELLOabcdefgADDNAME25abcdefgHELLOabcdefg" 
for word in $data \ 
    "ADDNAME25abcdefgHELLOabcdefgADDNAME25abcdefgHELLOabcdefg" \ 
    "ADDNAME25abcdefgHELLOabcdefgADDNAME25abcdefgHELLO" 
do 
    echo $word 
done | 
sed -e '/ADDNAME[0-9][0-9][a-z]*HELLO/{ 
     s/\(ADDNAME[0-9][0-9][a-z]*HELLO\)/ \1 /g 
     }' | 
while read line 
do 
    set -- $line 
    for arg in "[email protected]" 
    do echo $arg 
    done 
done | 
grep "ADDNAME[0-9][0-9][a-z]*HELLO" 

第一个循环呼应三行数据 - 你可能会替换成cat或我/ O重定向。 sed脚本使用修改后的正则表达式在模式周围放置空格。最后一个循环将'空格分隔的单词'分成每行一个'单词'。最后的grep选择你想要的行。

正则表达式被修改为[a-z]*代替原来的.*,因为模式匹配是贪婪的。如果ADDNAME和HELLO之间的数据是不受约束的,那么你就需要考虑使用非贪婪正则表达式,这在Perl可用,可能Python和其他现代脚本语言:

#!/bin/perl -w 
while (<>) 
{ 
    while (/(ADDNAME\d\d.*?HELLO)/g) 
    { 
     print "$1\n"; 
    } 
} 

这是使用的一个很好的示范工作的权利也是如此。