bash脚本提取正则表达式模式的所有匹配项

时间:2010-09-04 18:16:21

标签: bash shell

我发现了这个,但它假设这些单词是空格分隔的。

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的评论继续有意义。

3 个答案:

答案 0 :(得分:7)

编辑:回答已修改的问题:

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”。

答案 1 :(得分:4)

使用grep -o

  

-o, - only-matching仅显示匹配PATTERN

的行的部分

答案 2 :(得分: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 "$@"
    do echo $arg
    done
done |
grep "ADDNAME[0-9][0-9][a-z]*HELLO"

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

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

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

这是对工作使用权利的一个很好的证明。