就我而言,我想使用 sed 命令将一行分隔到单词,如下所示,尽管我应该都可以工作。
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/s+/n/g"
abc def gks dps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/s{1,}/n/g"
abc def gkn dpn
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/n/g"
abcndefngksndps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/:/g"
abc:def:gks:dps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ +/:/g"
abc def gks dps
但实际上,只有一个有效。
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/:/g"
abc:def:gks:dps
正则表达式中的s
字符集和+
特殊字符似乎不能很好地与 sed 命令配合使用。并且n
不被识别为新行。谁能告诉我为什么或提供一些线索。谢谢。
sed 匹配基本正则表达式,而元字符+
来自扩展正则表达式。POSIX 字符类[[:space:]]
的速记s
仅适用于某些 sed(例如 GNU sed)作为扩展。同样,n
在某些 sed 中只能用作"换行符"的含义,而在任何 sed 中,您可以使用反斜杠后跟文字换行符。你在脚本周围使用双引号 ("
) 而不是单引号 ('
) 会将其暴露给 shell,因此需要额外的反斜杠转义 - 始终在字符串或脚本周围使用单引号,除非您对双引号有非常特殊的需求(例如,让变量扩展),并且只使用双引号,除非您对 none 有非常具体的需求(例如,允许通配符扩展)。
在任何 POSIX sed 中做你想做的事情是:
$ echo 'abc def gks dps' | sed 's/[[:space:]][[:space:]]*/
/g'
abc
def
gks
dps
但这适用于 GNU sed(请注意为+
启用 ERE 的-E
- GNU sed 和 OSX/BSD sed 支持,但在这两个 sed 中,只有 GNU sed 支持s
和n
):
$ echo 'abc def gks dps' | sed -E 's/s+/n/g'
abc
def
gks
dps
有几个问题。首先,sed
默认使用基本的正则表达式,无法识别+
。对扩展正则表达式使用-E
修饰符,这样做。
其次,sed
不识别n
,但你可以使用ANSI C引用来使bash
理解它。但是,如果您只使用n
,则sed
模式中只有一个换行符,因此您必须转义换行符才能sed
字面上使用它;因此,您需要\
进行转义,n
换行符,总共三个反斜杠。
最后,s
作为一个字符类也不被原版sed
识别(但它在Linux发行版使用的GNUsed
上可用)。如果您需要与例如OSX(或brew install gnu-sed
)兼容,请使用文字空格。
echo "abc def gks dps" | sed -E $'s/ +/\n/g'
# => abc
# def
# gks
# dps