2016-01-21 72 views
1

x='abc.xyz'y='abc:xyz'以便滿足以下條件(打印「匹配」和「差異」):bash的變量和正則表達式比較

[[ "${x}" =~ abc".xyz" ]] && echo "matches" 
[[ "${y}" =~ abc".xyz" ]] || echo "diff" 

現在,字面l=".xyz"可以提取和測試仍然工作(注意雙引號l裁判):

[[ "${x}" =~ abc"${l}" ]] && echo "matches" 
[[ "${y}" =~ abc"${l}" ]] || echo "diff" 

而且問題:如果我們進一步嘗試r="abc\"${l}\""r="abc${l}",第一個測試永不打印「匹配」:

[[ "${x}" =~ ${r} ]] && echo "matches" 
[[ "${y}" =~ ${r} ]] || echo "diff" 

r的正確形式應該通過兩種測試?

+0

它適用於我 – anubhava

+0

@anubhava不,它沒有。這是一個微妙的bash問題。 –

+0

當然是這樣,[看這個demo](http://ideone.com/0nnx7v) – anubhava

回答

1

外殼命令行通常都加引號"刪除(他們控制 只有論點應該分裂與否),但有 是特殊處理後=~。引號在這裏像轉義一樣工作, 引號之間的所有內容都被處理爲僅匹配 的原始字符(除了變量替換$仍然有效)。

模式只有一個評估,因此隱藏在變量中的引號 被視爲普通引號,並且 不引發特殊引號語法。

您需要轉義$l 中的.(或任何其他活動)字符,並且引號語法在變量中不起作用。

如果$l始終等於.xyz,則可以使用r="abc\\${l}"以獲得正確的匹配。其等於r='abc\.xyz'

+2

把'\\'放入'r'賦值是非常奇怪的(因爲它假定知道'l'的內容) 。我應該這樣認爲。 –

+0

@Etan Reisner - 你是對的,但它是解決方法,絕對不是一個優雅的解決方案 - 可以引用'l'中的所有元字符。像'$ {l //./ \。}'這樣的東西可以在特殊情況下使用'l =「。xyz」'。在一般情況下(例如只在運行時才知道'l')括號,括號等等應該以相同的方式處理。它應該是''函數quote()...'並從代碼中調用。 –

+0

@jofel - 比引用'l'中的所有元字符有更好的方法。根據docs'模式的任何部分可能被引用來強制引用的部分匹配爲一個字符串.'它適用於模式'abc「.xyz」',它適用於'abc「$ {l}」'真正的痛苦是引入'r'和隨後的解引用。 –