我有一個殼變量:正則表達式的sed
all_apk_file="a 1 2.apk x.apk y m.apk"
我想要的a 1 2.apk
與TEST
來代替,使用命令:
echo $all_apk_file | sed 's/(.*apk){1}/TEST/g'
的.*apk
裝置結束與apk
,{1}
意味着只匹配一次,但不起作用;我只有原始變量作爲輸出:a 1 2.apk x.apk y m.apk
有誰能告訴我爲什麼?
我有一個殼變量:正則表達式的sed
all_apk_file="a 1 2.apk x.apk y m.apk"
我想要的a 1 2.apk
與TEST
來代替,使用命令:
echo $all_apk_file | sed 's/(.*apk){1}/TEST/g'
的.*apk
裝置結束與apk
,{1}
意味着只匹配一次,但不起作用;我只有原始變量作爲輸出:a 1 2.apk x.apk y m.apk
有誰能告訴我爲什麼?
一部分是在正規sed
,在()
和{}
在圖案普通字符,直到與反斜槓轉義。由於變量值中沒有括號,因此正則表達式永遠不會匹配。使用GNU sed
,您還可以使用-r
標誌啓用擴展正則表達式。如果你解決這個問題,你會再碰上這.*
是貪婪的問題,而g
修改實際上不會改變任何東西:因爲沒有在m.apk
後的空間
$ echo $all_apk_file | sed 's/\(.*apk \)\{1\}/TEST/g'
TESTy m.apk
$ echo $all_apk_file | sed -r 's/(.*apk){1}/TEST/g'
TESTy m.apk
$ echo $all_apk_file | sed -r 's/(.*apk){1}/TEST/'
TESTy m.apk
$
它只是停在那裏變量的回顯值。
現在的問題是:你想要取代什麼?這聽起來像'一切,直到包括第一次出現apk
在一個詞的結尾。這可能最容易通過Perl正則表達式中的尾隨上下文匹配或非貪婪匹配來完成。如果切換到Perl是一個選項,那麼這樣做。如果不是這樣,那麼在正則表達式中正常的sed
並不是微不足道的。
$ echo $all_apk_file | sed 's/^[^.]* [^.][^.]*\.apk /TEST /'
TEST x.apk y m.apk
$
這看起來對任何事情沒有這點,其次是一片空白,其次是沒有點了一遍,.apk
;這意味着允許的第一個點是2.apk
中的那個。它適用於樣本數據;如果變量包含:
all_apk_file="a 1.2 2.apk m.apk y.apk 37"
您需要調整它以符合您的要求。
thx,詳細和清晰。 – Searene 2012-02-22 15:00:06
首先,讓你熟悉sed
正則表達式,你需要使用-r
開關(SED -r ...):
echo $all_apk_file | sed -r 's/(.*apk){1}/TEST/g'
# returns TESTy m.apk
看什麼返回:TESTy m.apk
。這是因爲.*
是貪婪,所以它儘可能匹配。也就是說,.*
與a 1 2.apk x
匹配,並且您曾說過要替換.*apk
,即a 1 2.apk x.apk
與'TEST',導致TESTy m.apk
(注意正則表達式中'.apk'後面的空格,這就是爲什麼匹配並沒有擴展到最後一個'.apk',後面沒有空格)。
通常,一個可以改變.*
到.*?
使其非貪婪,但在sed不支持這種行爲。
所以,要解決它,你只需要讓你的正則表達式更具限制性。
很難說出你想做什麼 - 刪除「.apk」中第三個結尾的前三個單詞並替換爲「TEST」?在這種情況下,可以使用正則表達式:
[a-z0-9]+ +[a-z0-9]+ +[a-z0-9]+\.apk
結合的「i」切換(不區分大小寫)。
您必須給出決定刪除內容的邏輯(前三個單詞,第一個'.apk'單詞等任意數量的單詞),以便我們用正則表達式進一步幫助您。
其次,你已經把'g'開關放到你的正則表達式中。這意味着全部匹配模式將被替換,而您似乎只希望第一個被替換。所以刪除'g'開關。
最後,所有thse的組合:問題的
echo $all_apk_file | sed -r 's/[a-z0-9]+ +[a-z0-9]+ +[a-z0-9]+\.apk/TEST/i'
# TEST x.apk y m.apk
這可以在perl中用'echo $ all_apk_file | perl -pe's/^(。*?\。apk)/ TEST /''如果切換到perl是一個選項。 – AndrewF 2012-02-22 04:01:03
這可能會爲你工作:
echo "$all_apk_file" | sed 's/apk/\n/;s/.*\n/TEST/'
TEST x.apk y m.apk
至於爲什麼你的正則表達式沒有工作,看到@ mathematical.coffee和@Jonathan萊弗勒的優秀解釋。
s/apk/\n/
與s/apk/\n/1
同義,意思是用\n
代替第一次出現apk
。由於sed使用\n
作爲記錄分隔符,我們知道它不會發生在傳遞給sed命令的任何初始字符串中。有了我們腰帶上的這兩個事實,我們可以拆分字符串。
N.B.如果你想取代第二個apk
然後s/apk/\n/2
將符合該法案。當然,對於apk
的最後發生,則.*apk
發揮作用。
簡短回答是sed正在貪婪。既然你把'。*'作爲'。*'的一部分抓住前兩個'apk'組合,所以只能識別最後一個'apk'作爲最終組合。 – 2012-02-22 07:51:00