我有这个 POSIX 兼容的 shell 脚本。它需要一个带分隔符的字符串 w.r.t. |
如果子字符串的长度是单个字符,则将 -
添加到其前面:
#!/bin/sh
printf '%s\n' "k|k|jill|hill|k" | sed 's/\([|]\|^\)\([[:alnum:]]\)\([|]\|$\)/\1-\2\3/g'
这个输出:
-k|k|jill|hill|-k
请注意,它不考虑夹在两个定界符(即 |k|
)之间的 k。
更奇怪的是,如果我将原始代码段中的特殊字符更改为其他任何字符,它会在前面添加一个 -
(注意更改:^
到 something
;$
到 different
),但显然不是第一个和最后一个 k:
#!/bin/sh
printf '%s\n' "k|k|jill|hill|k" | sed 's/\([|]\|something\)\([[:alnum:]]\)\([|]\|different\)/\1-\2\3/g'
输出:
k|-k|jill|hill|k
起初我认为这是因为 $
和 ^
位置字符不是可选的。然而,对于第一个示例的第一个标志中的 $
和最后一个标志中的 ^
,它们显然是可选的。
我很好奇,为什么这不起作用,我可以用类似的 sed 表达式做我想做的事吗?
最佳答案
请注意,如果将 sed 脚本从全局搜索和替换更改为循环,则可以获得所需的输出:
printf '%s\n' "k|k|jill|hill|k" | sed 's/\([|]\|^\)\([[:alnum:]]\)\([|]\|$\)/\1-\2\3/g'
-k|k|jill|hill|-k
对比
printf '%s\n' "k|k|jill|hill|k" | sed '
:a
s/\([|]\|^\)\([[:alnum:]]\)\([|]\|$\)/\1-\2\3/
ta
'
-k|-k|jill|hill|-k
引用:https://www.gnu.org/software/sed/manual/html_node/Programming-Commands.html
关于regex - 奇怪的 sed 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48650329/