2017-10-19 22 views
0

所以我們的目標是用一個提供的正則表達式替換部分路徑名。 我想使用內置的正則表達式替代品$ {//路徑源/目標}Bash替換/ /不處理正則表達式的錨?因爲它是像glob一樣的

/tmp/some\/where/ is somewhat crude, as my_tmp would be matched to stupidity 
/\/tmp\//\/somewhere\// is better 
/^\/tmp\//\/somewhere\// is the best, but this last one doesn't seem to work. 

一個簡單的例子,因爲那些反斜槓是殺手:

$ t2="there hello" 
$ t1="hello there" 
$ echo ${t1//hello/goodbye} 
    goodbye there 
$ echo ${t2//hello/goodbye} 
    there goodbye 

但是讓我們說我只想要開始招呼:

$ echo ${t2//^hello/goodbye} 
    there hello   -- as required 

$ echo ${t1//^hello/goodbye} 
    hello there   -- but not what I want here 

-- ok let's try oldschool 
$ echo ${t2//~hello/goodbye} 
    there hello   -- as required 

$ echo ${t1//~hello/goodbye} 
    hello there   -- but not what I want here 

$ t3="^hello there" 

$ echo ${t3//^hello/goodbye} 
    goodbye there  --^is just a character :-(

但是對於=〜,我聽到你問...

$ if [[ $t1 =~ ^hello ]] ; then echo yes ; else echo no ; fi 
    yes 

$ if [[ $t2 =~ ^hello ]] ; then echo yes ; else echo no ; fi 
    no 

$ if [[ $t3 =~ ^hello ]] ; then echo yes ; else echo no ; fi 
    no 

所以,基本上=〜之間的行爲差​​異$ {//

我想我可以以某種方式使用=〜和$ BASH_REMATCH?

使用SED我得到預期的答案,但我真的不希望調用外部):

$ echo $t1 | sed s/^hello/goodbye/ 
    goodbye there 
$ echo $t2 | sed s/^hello/goodbye/ 
    there hello 
$ echo $t3 | sed s/^hello/goodbye/ 
    ^hello there 

GNU的bash,版本48年3月4日(1)-release下(x86_64-Linux PC的-gnu)

+0

你實際上是試圖取代一個正則表達式,或只是一個固定字符串(例如你好)?此外,雙斜線替換('$ {var // pattern/replacement}')替換了所有的事件,但是隻有一個錨點,所以單斜槓替換(只是第一次出現)更有意義。你想要做什麼? –

+0

我想我已經從路徑示例中明確了。在這種特殊情況下,我只想要與前面相匹配的替換品。 但是,通過命令行傳遞它的想法是由用戶決定的。 –

回答

3

bash manual(強調):

${parameter/pattern/string}

  • 模式被擴展爲產生一個模式,就像在文件擴展中一樣。 參數被擴大並且模式的最長匹配被替換爲字符串。如果模式以'/'開始,則模式的所有匹配被替換爲字符串。通常只有第一場比賽被取代。 如果模式以'#'開頭,則它必須在擴展值參數的開始處匹配。如果模式以'%'開始,則它必須在擴展值參數的末尾匹配。

請注意,由於錨定的模式只能匹配一次,因此對錨定模式進行重複搜索和替換是沒有意義的。因此,///#是互不兼容的。 (或者,更準確地說,在該${pattern//#.../...}#沒有特殊處理。)

由於手冊說,pattern是水珠,而不是一個正則表達式,所以它遵循相同的邏輯filename expansion。設置extglob將允許使用「擴展模式匹配字符」,這使得類似於正則表達式的模式成爲可能。

證據是在布丁:

$ t1="hello there" 
$ t2="there hello" 
$ echo ${t1/#hello/goodbye} 
goodbye there 
$ echo ${t2/#hello/goodbye} 
there hello 
+0

啊!所以他們只是發明了一些新的主播角色!如果他們工作,我可以愉快地記錄他們。 而我沒有找到的原因是我搜索「/ /」作爲命令,不/ /後跟/ 謝謝! –

+0

@Gem:'#'和'%'與前綴和後綴刪除一致(請參閱手冊中的'$ {parameter#pattern}'和'$ {parameter%pattern}'替代)與搜索和替換不同,那些符合Posix標準,因此已經存在了很長時間。 – rici