2017-07-12 14 views
2

我想在所有前面帶有字符('_')的地方用大寫字母替換下劃線,後面跟着大寫字母,例如: QWQW_IOIO,OP_FD_GF_JK,TRT_JKJ等。在整個文檔中需要替換。Vim或sed:替換模式中的字符

我試着用在vim替換這樣的: :%s/[A-Z]_[A-Z]/[A-Z]-[A-Z]/g 但是,這導致QWQW_IOIOQWQ[A-Z]-[A-Z]OIO :(

我使用sed命令嘗試: sed -i '/[A-Z]_[A-Z]/ s/_/-/g' ./file_name 這導致了更換整條生產線如

QWQW_IOIO variable may contain '_' or '-'線被替換

QWQW-IOIO variable may contain '-' or '-'

+0

下面的答案中的「捕獲組」與「sed」(除了'\ v'和'\ u'之外的東西)類似。請訪問http://grymoire.com/Unix/Sed.html#toc-uh-3以獲得一個溫和的介紹。祝你好運。 – shellter

回答

5

你對第一個vim方法有正確的想法。但是您需要使用捕獲組來記住[A-Z]部分中找到的字符。這些很好地解釋here:h /\1。作爲一個方面說明,我會建議使用\u而不是[A-Z],因爲它既短又快。這意味着你需要的解決方案是:

:%s/\(\u\)_\(\u\)/\1-\2/g 

或者,如果你想使用魔法設置,以使其更易於閱讀:

:%s/\v(\u)_(\u)/\1-\2/g 

另一種選擇是,以限制搜索的一部分這被替換爲\zs\ze原子:

:%s/\u\zs_\ze\u/-/g 

這是最短的解決方案,我所知道的。

2

這應該做你想做的,假設GNU sed。

sed -i -r -e 's/([A-Z]+)_([A-Z]+)/\1-\2/g' ./file_name 

說明:

-r標誌使延長的正則表達式

[A-Z]+是 「一個或多個大寫字母」

()團的圖案一起,並創建一個編號存儲匹配

\1\2把那些存儲在替換中的編輯匹配。

所以基本上這個發現的大寫字母加上下劃線,其次是大寫字母另一塊塊,記住只有字母塊爲2組,

([A-Z]+)_([A-Z]+) 

然後重放這些團體,但與連字符而不是下劃線。

\1-\2 

末的g標誌說,要做到這一點,即使模式多次顯示在同一行。

注意這分崩離析一點在這種情況下:

QWQW_IOIO_ABAB 

因爲它的第一次比賽,但不是第二;第二部分不匹配,因爲第一場比賽消耗了IOIO。因此,這將導致

QWQW-IOIO_ABAB 

這個版本滴+所以它只匹配一個大寫字母,並以同樣的方式不會打破:

sed -i -r -e 's/([A-Z])_([A-Z])/\1-\2/g' 

它仍然有一個小瑕疵,如果你有這樣一個字符串:

A_B_C 

和以前一樣的問題,只有一個字母,而不是多個。