假设我已输入:
/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在行的开头或结尾有一个空匹配运算符。那么,这是怎么做到的?
答案 0 :(得分:2)
您可以将所有斜杠翻译为+
,然后用斜杠替换+(在开头或结尾):
sed 'y/\//+/;s/^+\|+$/\//g;'
或者如果OR运算符不可用:
sed 'y/\//+/;s/^+/\//;s/+$/\//;'
如果更改分隔符以避免转义所有文字斜杠,则更好:
sed 'y~/~+~;s~^+\|+$~/~g;'
或者如果OR运算符不可用:
sed 'y~/~+~;s~^+~/~;s~+$~/~;'
(其中^
是该行开头的锚点,而$
是该行的
其他方法:您可以使用占位符保护要保留的斜杠:
sed 's~^/~{`%{~;s~/$~{`%{~;y~/~+~;s~{`%{~/~g;'
答案 1 :(得分:1)
如果您有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
答案 2 :(得分:0)
这是一个提供输出的sed命令:
sed -r 's=(.)/\b=\1+=g;' file
/
用作s命令的分隔符,但在这里我们使用=
/
匹配前面有某些内容(.
)并且我们处于单词边界(.)/(.)
,但这不起作用:
x/y/<
中,第二场比赛只会看到/z
而不是y/z
\b
第一场比赛不会消耗y
而第二场比赛会看到y/
答案 3 :(得分: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
第一个子项将所有a
更改为aA
。此时输入中没有字母a
,后面没有字母A
(我们需要先执行此操作,以确保在我们的第二个子字母后面只有aB
个输入是第二个子结果的结果
第二个子项将行的开头或结尾处的所有/
更改为aB
。此时,输入中唯一的aB
s位于行的开头或结尾处最初为/
的位置。
第3个子项将所有剩余的/
(即不在行的开头或结尾的那些)更改为+
。
第4个子点将aB
恢复为原始前/后/
。
第5个子点将aA
恢复为原始a
。
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed ':a;s/\([^\/]\)\/\([^\/]\)/\1+\2/g;ta' file
或者视觉上更容易:
sed -r ':a;s#([^/])/([^/])#\1+\2#g;ta' file
两次真正的regexp相同:
sed 's/\([^\/]\)\/\([^\/]\)/\1+\2/g;s/\([^\/]\)\/\([^\/]\)/\1+\2/g' file