有没有一种方法告诉sed只输出捕获的组?

例如,给定输入:

This is a sample 123 text and some 987 numbers

和模式:

/([\d]+)/

我能得到只有123和987输出的方式格式化后引用?


当前回答

我相信问题中给出的模式只是举例,目标是匹配任何模式。

如果你有一个允许在模式空间中插入换行符的GNU扩展sed,一个建议是:

> set string = "This is a sample 123 text and some 987 numbers"
>
> set pattern = "[0-9][0-9]*"
> echo $string | sed "s/$pattern/\n&\n/g" | sed -n "/$pattern/p"
123
987
> set pattern = "[a-z][a-z]*"
> echo $string | sed "s/$pattern/\n&\n/g" | sed -n "/$pattern/p"
his
is
a
sample
text
and
some
numbers

这些例子是用tcsh(是的,我知道它是错误的shell)和CYGWIN。(编辑:对于bash,删除set和=周围的空格。)

其他回答

Try

sed -n -e "/[0-9]/s/^[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\).*$/\1 \2 \3 \4 \5 \6 \7 \8 \9/p"

我在cygwin下得到了这个:

$ (echo "asdf"; \
   echo "1234"; \
   echo "asdf1234adsf1234asdf"; \
   echo "1m2m3m4m5m6m7m8m9m0m1m2m3m4m5m6m7m8m9") | \
  sed -n -e "/[0-9]/s/^[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\)[^0-9]*\([0-9]*\).*$/\1 \2 \3 \4 \5 \6 \7 \8 \9/p"

1234
1234 1234
1 2 3 4 5 6 7 8 9
$

Sed最多可以记住9个模式,但是您需要使用转义括号来记住正则表达式的部分内容。

请看这里的例子和更多细节

这不是OP要求的(捕获组),但你可以使用以下方法提取数字:

S='This is a sample 123 text and some 987 numbers'
echo "$S" | sed 's/ /\n/g' | sed -r '/([0-9]+)/ !d'

给出以下内容:

123
987

我想给出一个关于“仅输出使用sed捕获的组”的简单示例

我有/home/me/myfile-99,并希望输出文件的序列号:99

我的第一次尝试没有成功:

echo "/home/me/myfile-99" | sed -r 's/myfile-(.*)$/\1/'
# output: /home/me/99

为了做到这一点,我们还需要捕获捕获组中不需要的部分:

echo "/home/me/myfile-99" | sed -r 's/^(.*)myfile-(.*)$/\2/'
# output: 99

*)注意sed没有\d

您可以使用ripgrep,它似乎也是简单替换的sed替代品,就像这样

rg '(\d+)' -or '$1'

由于两次匹配,ripgrep使用-o或——only matching和-r或——replace两次只输出$1的第一个捕获组(引用以避免shell将其解释为变量)。