$ echo 'Number 123 inside text' | sed 's/[^0-9]*\([0-9]\{1,\}\)[^0-9]*/\1/'
123
s/[^0-9]* # several non-digits
\([0-9]\{1,\}\) # followed by one or more digits
[^0-9]* # and followed by more non-digits.
/\1/ # gets replaced only by the digits.
或者使用扩展语法(减少反引号并允许使用):
$ echo 'Number 123 in text' | sed -E 's/[^0-9]*([0-9]+)[^0-9]*/\1/'
123
要避免在没有数字时打印原始文本,请使用:
$ echo 'Number xxx in text' | sed -En 's/[^0-9]*([0-9]+)[^0-9]*/\1/p'
(-n)默认情况下不打印输入 .
(/ p)仅在更换完成后打印 .
并匹配几个数字(并打印它们):
$ echo 'N 123 in 456 text' | sed -En 's/[^0-9]*([0-9]+)[^0-9]*/\1 /gp'
123 456
$ str='This is a sample 123 text and some 987 numbers'
$ echo "$str" | sed -rn 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+([[:digit:]]+)[^[:digit:]]*/\1 \2/p'
该解决方案仅适用于(确切)两个数字运行 .
当然,由于答案是在shell中执行的,我们可以定义几个变量来缩短这样的答案:
$ str='This is a sample 123 text and some 987 numbers'
$ d=[[:digit:]] D=[^[:digit:]]
$ echo "$str" | sed -rn "s/$D*($d+)$D+($d+)$D*/\1 \2/p"
但是,正如已经解释的那样,使用 s/…/…/gp 命令更好:
$ str='This is 75577 a sam33ple 123 text and some 987 numbers'
$ d=[[:digit:]] D=[^[:digit:]]
$ echo "$str" | sed -rn "s/$D*($d+)$D*/\1 /gp"
75577 33 123 987
string='This is a sample 123 text and some 987 numbers'
echo "$string" | sed -rn 's/[^[:digit:]]*([[:digit:]]+)[^[:digit:]]+([[:digit:]]+)[^[:digit:]]*/\1 \2/p'
这说:
不默认打印每一行( -n )
排除零个或多个非数字
包括一个或多个数字
排除一个或多个非数字
包括一个或多个数字
排除零个或多个非数字
打印替换( p )
通常,在 sed 中,您使用括号捕获组并使用后引用输出捕获的内容:
echo "foobarbaz" | sed 's/^foo\(.*\)baz$/\1/'
将输出"bar" . 如果对扩展正则表达式使用 -r ( -E for OS X),则不需要转义括号:
S='This is a sample 123 text and some 987 numbers'
echo "$S" | sed 's/ /\n/g' | sed -r '/([0-9]+)/ !d'
给出以下内容:
123
987
5
我相信问题中给出的模式只是举例,目标是匹配 any 模式 .
如果你有一个带有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
8 回答
你可以使用grep
运行数字
此答案适用于任何数字组计数 . 例:
扩大答案 .
是 . 替换捕获组的所有文本:
或者使用扩展语法(减少反引号并允许使用):
要避免在没有数字时打印原始文本,请使用:
(-n)默认情况下不打印输入 .
(/ p)仅在更换完成后打印 .
并匹配几个数字(并打印它们):
这适用于任何数字运行计数:
这与grep命令非常相似:
关于\ d
Sed无法识别'\d'(快捷方式)语法 .
[0-9]
之上使用的ascii等价物并不完全等效 . 唯一的替代解决方案是使用字符类:'[[:digit:]]` .所选答案使用这样的“字符类”来构建解决方案:
该解决方案仅适用于(确切)两个数字运行 .
当然,由于答案是在shell中执行的,我们可以定义几个变量来缩短这样的答案:
但是,正如已经解释的那样,使用
s/…/…/gp
命令更好:这将涵盖重复的数字运行和编写短(呃)命令 .
尝试
我在cygwin下得到了这个:
Give up and use Perl
由于
sed
没有削减它,让我们抛出毛巾并使用Perl,至少它是LSB而grep
GNU扩展不是:-)输出:
输出:
随着背后:
输出:
输出:
随着背后:
输出:
让它发挥作用的关键是告诉
sed
排除您不想输出的内容以及指定您想要的内容 .这说:
不默认打印每一行(
-n
)排除零个或多个非数字
包括一个或多个数字
排除一个或多个非数字
包括一个或多个数字
排除零个或多个非数字
打印替换(
p
)通常,在
sed
中,您使用括号捕获组并使用后引用输出捕获的内容:将输出"bar" . 如果对扩展正则表达式使用
-r
(-E
for OS X),则不需要转义括号:最多可以有9个捕获组及其后引用 . 后引用按组显示的顺序编号,但它们可以按任何顺序使用,并且可以重复:
输出“a bar a” .
如果您有GNU
grep
(它也可以在BSD中工作,包括OS X):或变化,如:
-P
选项启用Perl兼容正则表达式 . 见man 3 pcrepattern或man 3 pcresyntax .Sed最多有九种记忆模式,但您需要使用转义括号来记住正则表达式的部分内容 .
有关示例和更多详细信息,请参阅here
这不是OP要求的(捕获组),但您可以使用以下方法提取数字:
给出以下内容:
我相信问题中给出的模式只是举例,目标是匹配 any 模式 .
如果你有一个带有GNU扩展名的 sed 允许在模式空间中插入换行符,一个建议是:
这些例子是使用CYGWIN的tcsh(是的,我 know 是错误的shell) . (编辑:对于bash,删除set,以及=周围的空格 . )