2016-02-14 83 views
0
月底開始模式

比方說,我有輸入:用sed來替換不在行

/a/b/c/d/e/ 
/a/b/c/d/e 
a/b/c/d/e/ 
a/b/c/d/e 

我想替換所有/是不是在邊緣與+所以輸出是:

/a+b+c+d+e/ 
/a+b+c+d+e 
a+b+c+d+e/ 
a+b+c+d+e 

我試過這個命令:

sed -e "s#\(.\)/\(.\)#\1+\2#g" 

是關閉b UT不大:

/a+b/c+d/e/ 
/a+b/c+d/e 
a+b/c+d/e/ 
a+b/c+d/e 

大概是因爲連續/人物之間的\(.\)重疊。

我不相信sed在行首或行結束時有一個空匹配運算符。那麼,這是如何完成的?

回答

2

可以將所有斜線轉化爲+,然後替換+(在開頭或結尾)用斜槓:

sed 'y/\//+/;s/^+\|+$/\//g;' 

或者如果OR運算符不可用E:

sed 'y/\//+/;s/^+/\//;s/+$/\//;' 

更好,如果你改變了分隔符,以避免逃避所有文字斜線:

sed 'y~/~+~;s~^+\|+$~/~g;' 

,或者OR操作符是不可用:

sed 'y~/~+~;s~^+~/~;s~+$~/~;' 

(其中^是該行開始的錨點並且$結束)


其他方式:您可以保護斜線你想用一個佔位符來保存:

sed 's~^/~{`%{~;s~/$~{`%{~;y~/~+~;s~{`%{~/~g;' 
1

如果你有perl你可以使用lookarounds此:

perl -pe 's~(?<!^)/(?!$)~+~g' file 

輸出:

/a+b+c+d+e/ 
/a+b+c+d+e 
a+b+c+d+e/ 
a+b+c+d+e 

否則,你可以使用這個sed 2的替代品:

sed -r 's~(.)/(.)~\1+\2~g; s~(.)/(.)~\1+\2~g' file 

或者這個sed機智,讓你的輸出

sed -r ':a;s|(.)/(.)|\1+\2|g;ta' file 
+1

或用小更改:'sed -r':a; s |(。)/(。)| \ 1+ \ 2 | g; ta'file'。 – Cyrus

+1

非常感謝@Cyrus,將它添加到我的答案中 – anubhava

0

這裏是一個sed命令::H標籤和循環

sed -r 's=(.)/\b=\1+=g;' file 
  • 通常/是用來作爲分隔符的指揮,但在這裏我們使用=
  • /匹配之前有一些東西(.)和我們在一個字邊界
  • 最初我試圖(.)/(.)但沒有奏效:
    • 第二點被消耗,下一場比賽只會之後開始,
    • 即在x/y/<的第二場比賽只能看到/z,而不是y/z
    • \b第一場比賽不消耗y和第二場比賽看到y/
0

這是做好工作像這樣常見的和非常有用的SED成語:

$ sed 's:a:aA:g; s:^/\|/$:aB:g; s:/:+:g; s:aB:/:g; s:aA:a:g' file 
/a+b+c+d+e/ 
/a+b+c+d+e 
a+b+c+d+e/ 
a+b+c+d+e 

第1小組將所有a s更改爲aA。那時在輸入中沒有字母a,沒有跟着字母A(我們需要首先確保在我們的第二個子輸入後只有aB s是第二個子結果)

第二個子將所有的/ s都在行的開始或結尾更改爲aB。在這一點上,輸入中唯一的aB s就是在線路開始或結束時最初爲/s的地方。

第三個子將所有剩餘的/ s(即那些不在該行的開頭或末尾的元素)更改爲+ s。

第4個子將aB恢復爲原始前端/末端/ s。

第5個子將aA恢復爲原來的a s。

0

這可能會爲你工作(GNU SED):

sed ':a;s/\([^\/]\)\/\([^\/]\)/\1+\2/g;ta' file 

或視覺簡單:

sed -r ':a;s#([^/])/([^/])#\1+\2#g;ta' file 

這是真的一樣正則表達式兩次:

sed 's/\([^\/]\)\/\([^\/]\)/\1+\2/g;s/\([^\/]\)\/\([^\/]\)/\1+\2/g' file