所以命令是:
echo "abc 123" | sed "s/[0-9]*/h/g"
我得到的输出为
hahbhch h
我如何得到这个输出?
我期望的输出是 abc h
我通过这个命令得到的:
echo "abc 123" | sed "s/[0-9][0-9]*/h/g"
有人可以解释一下吗..
答案1
这*
意味着零个或多个匹配,并且会尽快匹配。如果您在没有g
标志的情况下运行该命令(这意味着sed
将在第一次替换后停止),您将得到输出habc 123
。这是因为它从左到右开始读取,并且因为它无法 match a
,所以它只会匹配行的开头,然后停在那里。
使用全局 ( g
) 标志,它将继续尝试匹配字符串的其余部分,并且因为*
当它无法匹配其他任何内容时会匹配空字符串,所以h
每次它无法匹配更多数字时,它都会放置一个。
请注意,您的第二次尝试相当于sed "s/[0-9]\+/h/"
.这里的+
意思是一或更多匹配项,这意味着当它找不到要替换的数字时,它不会匹配空字符串。
答案2
答案与 sed 中处理正则表达式的方式有关。正则表达式或 RE 可能会变得非常复杂,并且需要在使用它们的功能和语法的复杂性之间进行权衡。不同的编程语言对于它们想要支持的功能和复杂性做出了不同的选择。 Sed 非常强大,因此比您想象的要复杂一些。为了得到答案,* 匹配前一个标记的零个或多个实例的序列。在您的情况下,前一个标记是 [0-9] ,表示任何数字。 Sed 注意到输入字符串中每个字符之前和之后都有一个零长度的数字字符串。在您习惯之前,这似乎相当违反直觉。您注意到解决该问题的一种常见方法是使用 /[0-9][0-9]*/ ,它被解释为一个数字后跟零个或多个数字。另一种解决方案是将 * 替换为 +。 + 匹配一个或多个前一个标记的序列。所以完整的命令是:
echo "abc 123" | sed "s/[0-9]+/h/g"
您可以使用在线手册(只需 google man sed)阅读有关 sed 命令的信息,或者如果您的系统上安装了手册,则只需运行命令“man sed”