28

sed 专家的另一个问题。

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

./pentaray_run2/Trace_220560.dat

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

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

sed "s/[^0-9]//g"

或仅提取第一个数字:

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

但我要的是第二个数字!!非常感谢任何帮助。

PS我所追求的数字始终是字符串中的第二个数字。

4

4 回答 4

26

这个可以吗?

sed -r 's/.*_([0-9]*)\..*/\1/g'

用你的例子:

kent$   echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*/\1/g'
220560
于 2012-10-19T12:21:13.763 回答
12

您可以使用以下方法提取最后一个数字:

sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/'

倒过来想这个更容易:

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

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

.*魔法是抵消(第 4 部分)从左到右的贪婪。如果没有第 3 部分,第 4 部分将消耗它所能消耗的所有内容,其中包括数字,但是有了它,匹配确保它停止,以允许至少一个非数字后跟一个数字被第 1 部分和第 2 部分消耗,允许捕获该数字。

于 2012-10-19T12:37:23.443 回答
7

如果grep欢迎:

$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+'
220560

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

echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/'
220560

我认为这种方法比使用更干净、更健壮sed

于 2012-10-19T12:25:34.400 回答
6

这可能对您有用(GNU sed):

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

这提取第二个数字:

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

这提取了第一个。

于 2012-10-19T12:58:45.260 回答