sed 捕获组不起作用

Mel*_*lab 55 sed

我有一个格式的字符串[0-9]+\.[0-9]+\.[0-9]。我需要分别提取第一个、第二个和第三个数字。据我了解,捕获组应该能够做到这一点。我应该能够用来sed "s/\([0-9]*\)/\1/g获得第一个数字,sed "s/\([0-9]*\)/\2/g获得第二个数字,并sed "s/\([0-9]*\)/\3/g获得第三个数字。不过,在每种情况下,我都得到了整个字符串。为什么会这样?

ter*_*don 81

如果没有您输入的示例,我们无法给您完整的答案,但我可以告诉您,您对捕获组的理解是错误的。您不按顺序使用它们,它们只引用同一替换运算符左侧的正则表达式。例如,如果您捕获 ,/(foo)(bar)(baz)/则foowill be \1、barwill be\2和bazwill be \3。你不能这样做s/(foo)/\1/; s/(bar)/\2/,因为在第二次s///调用中,只有一个被捕获的组,所以\2不会被定义。

因此,要捕获您的三组数字,您需要执行以下操作:

sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'
Run Code Online (Sandbox Code Playgroud)

或者,更具可读性:

sed -E 's/([0-9]*)\.([0-9]*)\.([0-9]*)/\1 : \2 : \3/'
Run Code Online (Sandbox Code Playgroud)

  • @乔什M。您需要对它们进行转义,以便使用它们来捕获模式。通常 sed 中的 `/(foo)/` 将匹配文字 `(` 字符,后跟 `foo` 和文字 `)`。如果要捕获一个组,则需要对括号进行转义或使用 `-E` 选项。 (7认同)
  • @乔什M。是的,`-r` 标志也能做到这一点,但它不可移植。GNU sed 支持它,但许多其他人不支持。`-E` 更通用。 (4认同)

小智 16

例子:

$ 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
Run Code Online (Sandbox Code Playgroud)

或者,一起:

$ echo "123.456.78" |sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1 : \2 : \3/'
123 : 456 : 78
Run Code Online (Sandbox Code Playgroud)


Sur*_*rya 9

将 Sed 与 -r、--regexp-extended 一起使用以避免所有转义括号。

echo "1234.567.89" | sed -r 's/([0-9]+)\.([0-9]+)\.([0-9]+)/\1, \2, \3/' 
1234, 567, 89    #output
Run Code Online (Sandbox Code Playgroud)