Bash:如何提取以 _ 开头和后跟的数字

Bash: How to extract numbers preceded by _ and followed by

我的文件名格式如下:filename_1234.svg

如何检索前面有下划线、后面有点的数字。 .svg

之前可以有一到四个数字

我试过:

width=${fileName//[^0-9]/}

但如果文件名也包含数字,它将 return 文件名中的所有数字,例如

file6name_1234.svg

我找到了两个下划线的解决方案(并将其拆分为一个数组),但我正在寻找一种方法来检查下划线和点。

试试下面的代码:

filename="filename_6_1234.svg"
if [[ "$filename" =~ ^(.*)_([^.]*)\..*$ ]];
then
    echo "${BASH_REMATCH[0]}" #will display 'filename_6_1234.svg'
    echo "${BASH_REMATCH[1]}" #will display 'filename_6'
    echo "${BASH_REMATCH[2]}" #will display '1234'
fi

解释:

  • =~ : bash 用于正则表达式比较的运算符
  • ^(.*)_([^.])\..*$ :我们寻找任何字符,然后是下划线,然后是任何字符,然后是点和扩展名。我们创建 2 个捕获组,一个用于最后一个下划线之前,一个用于 after
  • BASH_REMATCH : 包含捕获组的数组

我会用

sed 's!_! !g' | awk '{print "_" $NF}' 

从 filename_1234.svg 到 _1234.svg 然后

sed 's!svg!!g' 

删除扩展名。

多一条路

[akshay@localhost tmp]$ filename=file1b2aname_1234.svg
[akshay@localhost tmp]$ after=${filename##*_}
[akshay@localhost tmp]$ echo ${after//[^0-9]}
1234

使用awk

[akshay@localhost tmp]$ awk -F'[_.]' '{print }' <<< "$filename"
1234

如果你设置IFS,你可以使用Bash的内置read

这将通过下划线和点分割文件名并将结果存储在数组 a.

IFS='_.' read -a a <<<'file1b2aname_1234.svg'

这从数组中取出倒数第二个元素。

echo ${a[-2]}

您可以使用简单的参数扩展并删除子字符串 来简单地从右边 到 trim 直到并包括, '.',然后 trim 从 左边 '_',包括 '_',留下你想要的数字,例如

$ width=filename_1234.svg; val="${width%.*}"; val="${val##*_}"; echo $val
1234

注:#trim从首次出现## trim 到 最后一次出现 %%% 右侧 开始的工作方式相同。

解释:

  • width=filename_1234.svg - width 保存你的文件名

  • val="${width%.*}" - val 持有 filename_1234

  • val="${val##*_}" - 最后 val 成立 1234

当然,如果您的意图是 width 应该保持宽度,则不需要使用像 val 这样的临时值。我只是使用临时文件来防止更改 width 的原始内容。如果你想要width中的结果数,只需将上面各处的val替换为width并直接在width.

上操作即可

注 2: 使用 shell 功能,如 参数扩展 可防止创建单独的子 shell 和生成使用 sedgrepawk(或任何不属于 shell 的实用程序时发生的单独过程)。

有一个使用 cut 的解决方案:

name="file6name_1234.svg"
num=$(echo "$name" | cut -d '_' -f 2 | cut -d '.' -f 1)
echo "$num"

-d 用于指定分隔符。

-f指的是想要的字段。

我对性能一无所知,但它易于理解和维护。