使用sed和正则表达式从字符串中提取数字

Ste*_*ven 21 regex integer sed

针对sed专家的另一个问题.

我有一个表示路径名的字符串,其中包含两个数字.一个例子是:

./pentaray_run2/Trace_220560.dat
Run Code Online (Sandbox Code Playgroud)

我需要提取这些数字中的第二个 - 即220560

我(在论坛的帮助下)能够一起提取所有数字(即2220560):

sed "s/[^0-9]//g"
Run Code Online (Sandbox Code Playgroud)

或者只提取第一个数字:

sed -r 's|^([^.]+).*$|\1|; s|^[^0-9]*([0-9]+).*$|\1|'
Run Code Online (Sandbox Code Playgroud)

但我所追求的是第二个数字!! 任何帮助非常感谢.

PS我之后的数字始终是字符串中的第二个数字.

Ken*_*ent 18

这个可以吗?

sed -r 's/.*_([0-9]*)\..*/\1/g'
Run Code Online (Sandbox Code Playgroud)

用你的例子:

kent$   echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*/\1/g'
220560
Run Code Online (Sandbox Code Playgroud)


Jan*_*lho 9

你可以用这个提取最后的数字:

sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/'
Run Code Online (Sandbox Code Playgroud)

这倒是更容易思考:

  1. 从字符串的末尾开始,匹配零个或多个非数字字符
  2. 匹配(并捕获)一个或多个数字字符
  3. 匹配至少一个非数字字符
  4. 将所有字符与字符串的开头匹配

匹配的第3部分是"魔法"发生的地方,但它也限制你的匹配在数字之前至少有一个非数字(即你不能匹配一个只有一个数字的字符串开头的字符串,虽然有一个简单的解决方法,可以在字符串的开头插入一个非数字).

神奇的是反击.*(第4部分)从左到右的贪婪.如果没有第3部分,第4部分将尽其所能,包括数字,但有了它,匹配确保它停止,以便至少允许第1和第2部分使用非数字后跟数字,允许捕获数字.


Gil*_*not 7

如果grep欢迎:

$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+'
220560
Run Code Online (Sandbox Code Playgroud)

Perl使用相同的正则表达式更具便携性:

echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/'
220560
Run Code Online (Sandbox Code Playgroud)

我认为这种方法比使用更清洁,更健壮 sed


pot*_*ong 5

这可能适合你(GNU sed):

sed -r 's/([^0-9]*([0-9]*)){2}.*/\2/' file
Run Code Online (Sandbox Code Playgroud)

这提取了第二个数字:

sed -r 's/([^0-9]*([0-9]*)){1}.*/\2/' file
Run Code Online (Sandbox Code Playgroud)

这提取了第一个.