2012-12-19 166 views
1

我想要得到的字符串<sometag param=''>獲取字符串之間串在bash

之間我試圖用的方法,從Get any string between 2 string and assign a variable in bash獲得「X」:從

echo "<sometag param='x'><irrelevant stuff='nonsense'>" | tr "'" _ | sed -n 's/.*<sometag param=_\(.*\)_>.*/\1/p' 

的問題(除效率低,因爲我不能設法逃脫正確的撇號爲sed)是sed匹配的最大值,即輸出是:

x_><irrelevant stuff=_nonsense 

但正確的輸出將是最小的比賽,在這個例子只是「X」

感謝您的幫助

+0

對於結構化數據,使用一個工具,它理解結構體。 'man xsltproc' – tripleee

回答

3

您可能正在尋找這樣的事情:

sed -n "s/.*<sometag param='\([^']*\)'>.*/\1/p" 

測試:

echo "<sometag param='x'><irrelevant stuff='nonsense'>" | sed -n "s/.*<sometag param='\([^']*\)'>.*/\1/p" 

結果:

x 

說明:

  • 取而代之的是貪婪的捕獲,使用非貪婪的捕捉,如:[^']*這意味着匹配任何東西,除了'任意次數。爲了使圖案堅持下去,接下來是:'>
  • 您也可以使用雙引號,以便您不需要轉義單引號。如果你想逃避單引號,你可以這樣做:

-

... | sed -n 's/.*<sometag param='\''\([^'\'']*\)'\''>.*/\1/p' 

注意如何將單引號是不是真的逃脫。 sed表達式停止,插入轉義的單引號並重新打開sed表達式。把它看作是一個四字符轉義序列。我想使用GNU grep。它將使一個稍短的解決方案。運行像:

... | grep -oP "(?<=<sometag param=').*?(?='>)" 

測試:

echo "<sometag param='x'><irrelevant stuff='nonsense'>" | grep -oP "(?<=<sometag param=').*?(?='>)" 

結果:

x 
+1

謝謝,基於grep的解決方案就是我一直在尋找的。 – Robby75

+0

FYI:最後的grep測試表達不與OS X 10.11 grep的落實執行。一般來說,它可能不適用於BSD。它在Ubuntu上工作。 :) –

0

您不必組裝正則表達式在這種情況下,你可以使用'作爲字段分隔

in="<sometag param='x'><irrelevant stuff='nonsense'>" 

IFS="'" read x whatiwant y <<< "$in"   # bash 
echo "$whatiwant" 

awk -F\' '{print $2}' <<< "$in"     # awk 
相關問題