231

I want to parse a variable (in my case it's development kit version) to make it dot(.) free. If version='2.3.3', desired output is 233.

I tried as below, but it requires . to be replaced with another character giving me 2_3_3. It would have been fine if tr . '' would have worked.

  1 VERSION='2.3.3' 
  2 echo "2.3.3" | tr . _
8
  • 13
    No, it doesn't require: echo "2.3.3" | tr -d ..
    – manatwork
    Commented Dec 12, 2013 at 14:59
  • 1
    @manatwork Great, that works. You can post it as answer. Thanks Commented Dec 12, 2013 at 15:04
  • 2
    Lot of good answers. But if I can second-guess the objective, be warned about 2.11.3 and 2.1.13... ;-) Consider adding padding zeroes to numbers.
    – Rmano
    Commented Dec 12, 2013 at 16:06
  • 1
    @Rmano You mean something like VERSION='2.30.3100'? No matter what just .'s are removed with all of the answers here. Commented Dec 12, 2013 at 16:13
  • 2
    @PrayagUpd --- I simply meant that if you will use the number after the conversion for comparisons (as to say if "is this version newer or the same") you should take care of cases like 2.11.3 and 2.1.13 --- they seems the same after dot removal, but clearly 2.11.3 is newer. Also, 2.11.3 is newer than 2.1.14, but comparing 2113 and 2114 will lead to the wrong answer. I remember a bug somewhere for this...
    – Rmano
    Commented Dec 12, 2013 at 16:19

6 Answers 6

255

There is no need to execute an external program. bash's string manipulation can handle it (also available in ksh93 (where it comes from), zsh and recent versions of mksh, yash and busybox sh (at least)):

$ VERSION='2.3.3'
$ echo "${VERSION//.}"
233

(In those shells' manuals you can generally find this in the parameter expansion section.)

8
  • 59
    For further detail, the syntax of the above answer is ${string//substring/replacement}, where apparently the lack of the final forward slash and replacement string are interpreted as delete. See here.
    – sherrellbc
    Commented Jan 6, 2016 at 18:19
  • 7
    Right, man bash says it clearly in the Shell Parameter Expansion section: “${parameter/pattern/string} (…) If string is null, matches of pattern are deleted and the / following pattern may be omitted.”
    – manatwork
    Commented Jan 6, 2016 at 18:49
  • 1
    My issue was that the version number came like this "1.0.0" and I wanted just the number so follow what @manatwork suggested I changed in: "${VERSIONNUM//'"'}" however I insert even ' ' because otherwise it wouldn't recognise the "" like string to take off. Commented Sep 14, 2016 at 12:53
  • 1
    @Alexiscanny, you mean literal " are present in the value? I'm afraid this counts as new question, but try to just escape the doublequote: "${VERSIONNUM//\"}" pastebin.com/3ECDtkwH
    – manatwork
    Commented Sep 14, 2016 at 13:03
  • 1
    Superb!! works on -ash too!
    – Fr0zenFyr
    Commented Jan 4, 2017 at 11:33
138

By chronological order:

tr/sed

echo "$VERSION" | tr -d .
echo "$VERSION" | sed 's/\.//g'

csh/tcsh

echo $VERSION:as/.//

POSIX shells:

set -f
IFS=.
set -- $VERSION
IFS=
echo "$*"

ksh93/zsh/mksh/bash/yash (and busybox ash when built with ASH_BASH_COMPAT)

echo "${VERSION//.}"

zsh

echo $VERSION:gs/./
1
  • 1
    tr -d deleted even single char from the set. For Ex i want to delete DCC_ from "DCC_VersionD", It deletes DCC and D. Expected output : VersionD. Actual Output : Version. sed worked like a charm. :) thanks for the post.
    – kayle
    Commented May 21, 2018 at 11:30
32

In addition to the successful answers already exists. Same thing can be achieved with tr, with the --delete option.

echo "2.3.3" | tr --delete .
echo "2.3.3" | tr -d .       # for MacOS

Which will output: 233

1
  • 11
    on macos the --delete flag is not recognised, but you can use -d instead
    – Anentropic
    Commented Apr 5, 2018 at 17:40
11

You should try with sed instead

sed 's/\.//g'
1
  • A POSIX compliant one liner, nice. Commented Feb 23, 2023 at 18:55
7
echo "$VERSION" | tr -cd [:digit:]

That would return only digits, no matter what other characters are present

1
  • Only if there's no file called :, d, i, g or t in the current directory and you're using a shell that doesn't complain upon non-matching globs and leaves them asis (most Bourne-like ones and rc-like ones) or a shell that doesn't support [...] globs (like fish). Commented May 29, 2020 at 15:17
5

Perl

$ VERSION='2.3.3'                                     
$ perl -pe 's/\.//g' <<< "$VERSION"           
233

Python

$ VERSION='2.3.3'                                     
$ python -c 'import sys;print sys.argv[1].replace(".","")' "$VERSION"
233

If $VERSION only contains digits and dots, we can do something even shorter:

$ python -c 'print "'$VERSION'".replace(".","")'
233

(beware it's a code injection vulnerability though if $VERSION may contain any character).

AWK

$ VERSION='2.3.3'
$ awk 'BEGIN{gsub(/\./,"",ARGV[1]);print ARGV[1]}' "$VERSION"
233

Or this:

$ awk '{gsub(/\./,"")}1' <<< "$VERSION"
233

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .