获取文件名中位于文件扩展名前的数字,同时考虑其他可能存在的数字。

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中完成。非常感谢您的帮助。


当你说你必须“在bash中执行它”时,这是否意味着你不能使用像perl或sed这样的命令行实用程序? - Brian Warshaw
我可以使用sed,但不能使用perl。基本上,我不被允许使用所有项目中每个人都可以使用的工具。Sed、awk和bash几乎是唯一可用的工具。 - RJS
5个回答

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

这里使用了bash中备受忽视的=~正则表达式运算符,它会将匹配结果存储在一个名为BASH_REMATCH的数组中。

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

1
你可以使用参数替换来实现这个功能。

var=kej10_sdlkei450_sdlekr_310.txt
var=${var%.*}
var=${var##*_}
echo $var
310

0
这应该解决了你的问题:
INPUT="some6random7numbers_12345_moreletters_789.txt"
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)'`
echo $SUBSTRING

这将输出789


0

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

var="kej10_sdlkei450_sdlekr_310.txt"
v=$(IFS=[_.] read -ra arr <<< "$var" && echo "${arr[@]:(-2):1}")
echo "$v"
310

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接