Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have the following format for filenames: filename_1234.svg

How can I retrieve the numbers preceded by an underscore and followed by a dot. There can be between one to four numbers before the .svg

I have tried:

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

but if the fileName contains a number as well, it will return all numbers in the filename, e.g.

file6name_1234.svg

I found solutions for two underscores (and splitting it into an array), but I am looking for a way to check for the underscore as well as the dot.

like image 408
TheRed Avatar asked Dec 08 '25 13:12

TheRed


1 Answers

You can use simple parameter expansion with substring removal to simply trim from the right up to, and including, the '.', then trim from the left up to, and including, the '_', leaving the number you desire, e.g.

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

note: # trims from left to first-occurrence while ## trims to last-occurrence. % and %% work the same way from the right.

Explained:

  • width=filename_1234.svg - width holds your filename

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

  • val="${val##*_}" - finally val holds 1234

Of course, there is no need to use a temporary value like val if your intent is that width should hold the width. I just used a temp to protect against changing the original contents of width. If you want the resulting number in width, just replace val with width everywhere above and operate directly on width.

note 2: using shell capabilities like parameter expansion prevents creating a separate subshell and spawning a separate process that occurs when using a utility like sed, grep or awk (or anything that isn't part of the shell for that matter).

like image 86
David C. Rankin Avatar answered Dec 11 '25 03:12

David C. Rankin