rp346
rp346

Reputation: 7028

bash extract version string & convert to version dot

I want to extract version string (1_4_5) from my-app-1_4_5.img and then convert into dot version (1.4.5) without filename. Version string will have three (1_4_5) or four (1_4_5_7) segments.

Have this one liner working ls my-app-1_4_5.img | cut -d'-' -f 3 | cut -d'.' -f 1 | tr _ .

Would like to know if there is any better way rather than piping output from cut.

Upvotes: 0

Views: 428

Answers (6)

accdias
accdias

Reputation: 5372

Assuming the version number will always be between the last dash and the file extension, you can use something like this in pure Bash:

name="file-name-x-1_2_3_4_5.ext"
version=${name##*-}
version=${version%%.ext}
version=${version//_/.}
echo $version

The code above will result in:

1.2.3.4.5

For a complete explanation about the brace expansions used above, please take a look at Bash Reference Manual: 3.5.1 Brace Expansion.

Upvotes: 2

Ivan
Ivan

Reputation: 7253

A slightly shorter variant

name=my-app-1_4_5.img
vers=${name//[!0-9_]}
$ echo ${vers//_/.}
1.4.5

Upvotes: 0

Cyrus
Cyrus

Reputation: 88543

With bash and a regex:

echo "my-app-1_4_5.img" | while IFS= read -r line; do [[ "$line" =~ [^0-9]([0-9_]+)[^0-9] ]] && echo "${BASH_REMATCH[1]//_/.}"; done

Output:

1.4.5

Upvotes: 1

Cyrus
Cyrus

Reputation: 88543

Remove everything but 0 to 9, _ and newline and then replace all _ with .:

echo "my-app-1_4_5.img" | tr -cd '0-9_\n' | tr '_' '.'

Output:

1.4.5

Upvotes: 1

tripleee
tripleee

Reputation: 189307

Here's an attempt with parameter expansion. I'm assuming you have a wildcard pattern you want to loop over.

for file in *-*.img; do
    base=${file%.img}
    ver=${base##*-}
    echo "${ver//_/.}"
done

The construct ${var%pattern} returns the variable var with any suffix matching pattern trimmed off. Similarly, ${var#pattern} trims any prefix which matches pattern. In both cases, doubling the operator switches to trimming the longest possible match instead of the shortest. (These are POSIX-compatible pattenr expansion, i.e. not strictly Bash only.) The construct ${var/pattern/replacement} replaces the first match in var on pattern with replacement; doubling the first slash causes every match to be replaced. (This is Bash only.)

Upvotes: 3

Beglex
Beglex

Reputation: 58

You can do it with sed:

sed -E "s/.*([0-9]+)_([0-9]+)_([0-9]+).*/\1.\2.\3/" <<< my-app-1_4_5.img

Upvotes: 2

Related Questions