[英]Use sed to replace patterns that are not at the start of end of lines
假設我輸入了:
/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"
這很接近但不完全是:
/a+b/c+d/e/
/a+b/c+d/e
a+b/c+d/e/
a+b/c+d/e
大概是因為\\(.\\)
在連續的/
字符之間重疊。
我不認為sed在行首或行尾有空匹配運算符。 那么,這是怎么做的呢?
您可以將所有斜杠轉換為+
,然后用斜杠替換+(在開頭或結尾):
sed 'y/\//+/;s/^+\|+$/\//g;'
或如果OR運算符不可用:
sed 'y/\//+/;s/^+/\//;s/+$/\//;'
如果更改定界符以避免轉義所有文字斜杠,則更好:
sed 'y~/~+~;s~^+\|+$~/~g;'
或如果OR運算符不可用:
sed 'y~/~+~;s~^+~/~;s~+$~/~;'
(其中^
是該行開頭的錨點, $
是該行的結尾)
其他方式:您可以使用占位符保護要保留的斜杠:
sed 's~^/~{`%{~;s~/$~{`%{~;y~/~+~;s~{`%{~/~g;'
如果您有perl
,則可以使用環視方法:
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 -r ':a;s|(.)/(.)|\1+\2|g;ta' file
這是一個sed命令,可提供您的輸出:
sed -r 's=(.)/\b=\1+=g;' file
/
用作s命令的分隔符,但這里我們使用=
/
匹配在前面有( .
)且我們位於單詞邊界的地方 (.)/(.)
但是沒有用:
x/y/<
,第二個匹配項只會顯示/z
而不是y/z
\\b
,第一個匹配項不會消耗y
,第二個匹配項會看到y/
這是完成以下工作的常見且極為有用的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
第一個子將所有a
更改為aA
。 在這一點上,輸入中沒有字母a
,后跟字母A
(我們需要首先執行此操作,以確保在第二個子之后,輸入中僅有的aB
是該第二個子的結果)
第二個子句將行的開頭或結尾的全部/
s更改為aB
。 在那一點上,輸入中唯一的aB
是行的開始或結尾處最初存在/
s的位置。
第3個子項將所有剩余的/
s(即不在行首或末尾的/
s)更改為+
s。
的第四子恢復aB
的背部到原來的前/結束/
秒。
第五個子將aA
s恢復為原始a
s。
這可能對您有用(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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.