我有一个格式的字符串[0-9]+\.[0-9]+\.[0-9]
。我需要分别提取第一个、第二个和第三个数字。据我了解,捕获组应该能够做到这一点。我应该能够用来sed "s/\([0-9]*\)/\1/g
获取第一个数字、sed "s/\([0-9]*\)/\2/g
第二个数字和sed "s/\([0-9]*\)/\3/g
第三个数字。但在每种情况下,我都会得到整个字符串。为什么会发生这种情况?
答案1
如果没有您输入的示例,我们无法给您完整的答案,但我可以告诉您,您对捕获组的理解是错误的。您不按顺序使用它们,它们仅引用同一替换运算符左侧的正则表达式。例如,如果您捕获 ,/(foo)(bar)(baz)/
那么foo
will be \1
、bar
will be\2
和baz
will be \3
。你不能这样做s/(foo)/\1/; s/(bar)/\2/
,因为在第二次s///
调用中,只有一个捕获组,因此\2
不会被定义。
因此,要捕获三组数字,您需要执行以下操作:
sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'
或者,更具可读性:
sed -E 's/([0-9]*)\.([0-9]*)\.([0-9]*)/\1 : \2 : \3/'
答案2
例子:
$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'
123
$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'
456
$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'
78
或者,一起:
$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'
123 : 456 : 78
答案3
将 Sed 与 -r, --regexp-extended 一起使用以避免所有转义的括号。
echo "1234.567.89" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1, \2, \3/'
1234, 567, 89 #output