2014-02-09 48 views
2

我有問題了解我的正則表達式在bash shell中的確正在做什麼。正則表達式匹配只有數字

我有字符串abcde 12345 67890testing。我想使用sed從這個字符串中提取12345

但是,使用sed -re 's/([0-9]+).*/\1/'對給定的字符串將給我abcde 12345。另外,使用sed -re 's/([\d]+).*/\1/'實際上只提取abcd

我錯了,假設表達式[0-9][\d]只捕獲數字?我不知道如何abcd被捕獲,但字符串67890不是。另外,我想知道爲什麼在我的第一個查詢中捕獲空間?另外,sed -re 's/^.*([0-9]+).*/\1/'給我0。在這種情況下,我完全不明白正則表達式在做什麼。我以爲表達式^.*[0-9]+只會捕獲一串唯一數字的第一個實例?不過,它只匹配最後一個0.總之,我想了解我對所有這些問題的看法。以及如何在正則表達式中使用[\ s]來解決問題,以隔離第一個數字串。

+0

問題是你的'sed'命令是這樣的:「在每一行上,找到一些數字後跟任意數量的字符,一個用數字替換那個匹配。「它正在執行指定的內容,即用'12345'替換12345 67890testing'。相反,你想用什麼都替換最初的匹配。不幸的是,據我所知,沒有辦法在'sed'表達式的前面放置一個非貪婪的'。*?',而內聯Perl或Ruby可能是更好的選擇。 – chrylis

回答

0

您可以使用:

sed 's/^\([0-9]*\).*$/\1/g' <<< "$s" 
12345 

否則修改您的sed:

sed 's/\([0-9]\+\).*/\1/g' <<< "$s" 
12345 

你一定要逃逸無擴展的正則表達式標誌(-r OR -E)的sed + & (and)

-r這將是:

sed -r 's/([0-9]+).*/\1/g' <<< "$s" 
12345 

UPDATE:你並不真的需要這方面的任何外部工具,你可以使用正則表達式的能力,這樣做在BASH本身:

[[ "$s*" =~ ^([0-9]+) ]] && echo "${BASH_REMATCH[1]}" 
12345 
+0

謝謝你的回覆。然而,使用'sed -r'/([0-9] +)。*/\ 1/g'<<<「$ s」'會使我產生'abcd 12345' 我不確定它是如何抓住'abcd' – user3289476

+0

'sed -r's /([0-9] +)。*/\ 1/g'<<<「$ s」'給我'12345' – anubhava

+1

您能否解釋一下使用背後的想法這是一個字符串?據我所知,這只是在Bash變量's'的內容上運行'sed'表達式,這似乎沒有幫助。 – chrylis

3
sed -E 's/([0-9]+).*/\1/g' <<< "$s" 

上面的命令意味着:找到一個數字序列後面跟一個東西,並用數字替換它。所以它匹配12345 67890測試並且僅用來代替它。

最後的字符串將是abcd 12345

如果你只想得到12345,你應該使用grep。

egrep -o '[0-9]+ ' <<< "$s" 

或者使用sed,您可以使用:

sed -E 's/[a-zA-Z ]*([0-9]+).*/\1/g' <<< "$s" 

這將數字

+0

對於我的最後一次嘗試,是使用貪婪的表達式'。*'進入字符串的其餘部分,直到它只剩下'0'?似乎不可能使用貪婪的表達式去除前面的問題的abcde部分呢? – user3289476

+0

如果你使用。*([0-9] +)。*它只會匹配最後一個數字,因爲+意味着1或更多,所以它會最小化。如果你確切地知道你可以使用的數字序列的長度,*([0-9] {5})。*和)之間必須有一個空格。 – drolando

0

之前下降的字母,因爲別人已經具備SED,grep的解決方案,這裏是awk的代碼:

echo "abcde 12345 67890testing"|awk '{for (i=1;i<=NF;i++) if ($i~/^[0-9]+$/) print $i}'