2010-09-04 78 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"; 
    } 
} 

這是使用的一個很好的示範工作的權利也是如此。