我有一个像这样的形式的字符串结构bob-type-8.2-mp2-2017-93-43-11-65-48.spr
,我只需要提取8.2-mp2-2017-93-43-11-65-48
.
这意味着输出字符串应该包含遇到第一个数值后的所有字符,然后从中删除.spr
。
我怎样才能做到这一点?
答案1
尝试这个:
echo "bob-type-8.2-mp2-2017-93-43-11-65-48.spr" | sed 's/^[^0-9]*//;s/\.[^.]*$//'
输出将:
8.2-mp2-2017-93-43-11-65-48
解释:
sed 使用模式 's/pattern/replace_pattern/'
来查找pattern
并将其替换为replace_pattern
因此,模式's/^[^0-9]*//'
从行首和第一个数字出现之前获取所有符号,并将其替换为空(replace_pattern
空)。
下一步 - 删除扩展。我们可以使用相同的 sed 模式来做到这一点's///'
。
s/\.[^.]*$//
.
- 找到行尾不是 a 的所有符号$
并将其替换为空。
;
- 划分模式。
为了更好地理解,您可以使用以下命令:
echo "bob-type-8.2-mp2-2017-93-43-11-65-48.spr" | sed -e 's/^[^0-9]*//' -e 's/\.[^.]*$//'
答案2
在 Bash 中,与extglob
:
$ shopt -s extglob
$ var=bob-type-8.2-mp2-2017-93-43-11-65-48.spr
$ res=${var##*([^0-9])}
$ res=${res%.spr}
$ echo "$res"
8.2-mp2-2017-93-43-11-65-48
*([^0-9])
匹配任何非数字字符串,${var##pattern}
从字符串开头删除最长的匹配模式,${var%pattern}
从末尾删除(最短)匹配模式。
答案3
另一种方法是sed
.
sed 's/^[^[[:digit:]]*\(.*\)\.spr$/\1/' <<<"bob-type-8.2-mp2-2017-93-43-11-65-48.spr"
^[^[[:digit:]]*
匹配从字符串开头开始直到看到第一个数字的所有内容;与...一样^[^0-9]*
\(.*\)
匹配上述匹配之后的所有内容,并且括号\(...\)
用于捕获组匹配\1
作为其反向引用。\.spr$
匹配spr
输入字符串末尾的文字点。\1
仅打印捕获的组比赛。
答案4
POSIXly:
string=bob-type-8.2-mp2-2017-93-43-11-65-48.spr
newstring=${string#"${string%%[0-9]*}"}
newstring=${newstring%.*}
${string#pattern}
:从开头删除$string
匹配的内容pattern
,在本例中是:${string%%[0-9]*}
$string
删除与[0-9]*
模式匹配的最长尾部部分。这就是第一个数字之前的部分。${newstring%.*}
:$string
剥夺了它的最短与模式匹配的尾部部分.*
。所以删除扩展名。
和zsh
:
newstring=${(M)${string:r}%%[0-9]*}
${string:r}
: 扩展到根名(删除扩展名)就像csh
${(M)var%%pattern}
,返回操作M
符所附加的内容%%
(如果没有,(M)
将删除末尾与 POSIX shell 中的模式匹配的最长部分)。