从文件扩展名之前的文件名中获取数字,文件名中包含其他数字

时间:2013-09-03 17:47:47

标签: regex bash

我正在尝试在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中这样做。真的很感激任何帮助。

5 个答案:

答案 0 :(得分:2)

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

这使用bash的低估的=~正则表达式运算符,该运算符将匹配存储在名为BASH_REMATCH的数组中。

答案 1 :(得分:1)

您可以使用参数替换

来执行此操作
var=kej10_sdlkei450_sdlekr_310.txt
var=${var%.*}
var=${var##*_}
echo $var
310

答案 2 :(得分:1)

使用一系列Bash Shell扩展

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

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

答案 3 :(得分:0)

这应该照顾你的情况:

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

这将输出789

答案 4 :(得分:0)

此处不需要正则表达式,您可以使用IFS

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