3

我试图在 bash 脚本中提取文件扩展名之前的最后一个数字。所以格式会有所不同,但它会是数字和字母的某种组合,最后一个字符将始终是数字。我需要提取这些数字并将它们存储在一个变量中。

格式一般为:

sdflkej10_sdlkei450_sdlekr_1.txt

我只想将最后一位数字 1 存储到变量中。

我将使用它来遍历大量文件,最后一个数字将变为两位数和三位数。

所以对于这个文件:

kej10_sdlkei450_sdlekr_310.txt

我需要退回310。

字母数字字符和下划线的数量因每个文件而异,但我想要的数字始终位于 .txt 扩展名之前和下划线之后。

我试过了:

bname=${f%%.*}
number=$(echo $bname | tr -cd '[[:digit:]]') 

但这会返回所有数字。

如果我尝试

number = $(echo $(bname -2) it changes the number it returns.

我遇到的问题主要与可变性有关,以及我被要求在 bash 中执行此操作的事实。任何帮助将不胜感激。

4

5 回答 5

2
regex='([0-9]+)\.[^.]*$'
[[ $file =~ $regex ]] && number=${BASH_REMATCH[1]}

这使用了 bash 被低估的=~正则表达式运算符,它将匹配项存储在一个名为BASH_REMATCH.

于 2013-09-03T17:53:40.383 回答
1

您可以使用参数替换来做到这一点

var=kej10_sdlkei450_sdlekr_310.txt
var=${var%.*}
var=${var##*_}
echo $var
310
于 2013-09-03T17:59:56.347 回答
1

使用一系列 Bash Shell 扩展

虽然不是最优雅的解决方案,但这个解决方案使用一系列shell 参数扩展来实现所需的结果,而无需定义特定的扩展。例如,此函数使用长度和偏移扩展来查找删除文件扩展名后的数字:

extract_digit() {
    local basename=${1%%.*}
    echo "${basename:$(( ${#basename} - 1 ))}"
}

捕获函数输出

您可以使用以下内容捕获变量中的输出:

$ foo=$(extract_digit sdflkej10_sdlkei450_sdlekr_1.txt)
$ echo $foo
1

函数的示例输出

$ extract_digit sdflkej10_sdlkei450_sdlekr_1.txt
1

$ extract_digit sdflkej10_sdlkei450_sdlekr_9.txt
9

$ extract_digit sdflkej10_sdlkei450_sdlekr_10.txt
0
于 2013-09-03T18:09:36.600 回答
0

这里不需要正则表达式,你可以利用IFS

var="kej10_sdlkei450_sdlekr_310.txt"
v=$(IFS=[_.] read -ra arr <<< "$var" && echo "${arr[@]:(-2):1}")
echo "$v"
310
于 2013-09-03T18:20:14.853 回答
0

这应该照顾你的情况:

INPUT="some6random7numbers_12345_moreletters_789.txt"
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)'`
echo $SUBSTRING

这将输出789

于 2013-09-03T18:05:46.660 回答