Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Increment integer using Shell

1,357 views
Skip to first unread message

Geezer From The Freezer

unread,
Sep 6, 2005, 11:05:43 AM9/6/05
to
I want to increment a variable without using expr, and using
just shell builtins

i.e:-
VAR=1
VAR=`expr $VAR + 1`

I've seen it done before, but can't remember how its done using
sh or ksh - any pointers please?

Christophe Gaubert

unread,
Sep 6, 2005, 11:15:52 AM9/6/05
to
Geezer From The Freezer a écrit :

With bash, I can do :
(( var= $var + 1 ))
# or :
let "var=var+1"

I don't know if it's bash-specific ?


--
Christophe Gaubert
http://perso.wanadoo.fr/christophe.gaubert
Mail posté depuis un systčme libre GNU/Linux

Christophe Gaubert

unread,
Sep 6, 2005, 11:22:11 AM9/6/05
to
Christophe Gaubert a écrit :

> I don't know if it's bash-specific ?

At least, if I run bash with the "--posix" option, it works.

Mail posté depuis un système libre GNU/Linux

Bill Marcum

unread,
Sep 6, 2005, 11:18:50 AM9/6/05
to

VAR=$((VAR+1))

--
Atlanta makes it against the law to tie a giraffe to a telephone pole
or street lamp.

William

unread,
Sep 6, 2005, 11:49:42 AM9/6/05
to
"Geezer From The Freezer" <Gee...@freezer.commy> wrote in message
news:dfkb88$c...@netnews.net.lucent.com...

Do a groups search on Google within this newsgroup. There was a
LOT of traffic on ways to do this a couple of years ago. To get
you started, here's one version derived from that discussion
that I've used recently:

IncVar () # varname
{
eval 'IV_V="${'$1':-0}"' ; IV_C=1
while : ; do
case "${IV_V}.$IV_C" in
${IV_P}.*) break ;;
# This would trim up to four leading 0s
# 0${IV_P}.*|00${IV_P}.*|000${IV_P}.*|0000${IV_P}.*) break ;;
*9${IV_P}.1) IV_NV="0$IV_NV" ; IV_P="?$IV_P" ; continue ;;
*9${IV_P}.|*8${IV_P}.1) IV_NV="9$IV_NV" ;;
*8${IV_P}.|*7${IV_P}.1) IV_NV="8$IV_NV" ;;
*7${IV_P}.|*6${IV_P}.1) IV_NV="7$IV_NV" ;;
*6${IV_P}.|*5${IV_P}.1) IV_NV="6$IV_NV" ;;
*5${IV_P}.|*4${IV_P}.1) IV_NV="5$IV_NV" ;;
*4${IV_P}.|*3${IV_P}.1) IV_NV="4$IV_NV" ;;
*3${IV_P}.|*2${IV_P}.1) IV_NV="3$IV_NV" ;;
*2${IV_P}.|*1${IV_P}.1) IV_NV="2$IV_NV" ;;
*1${IV_P}.|*0${IV_P}.1) IV_NV="1$IV_NV" ;;
*0${IV_P}.) IV_NV="0$IV_NV" ;;
esac
unset IV_C ; IV_P="?$IV_P"
done
eval $1'="$IV_C$IV_NV"'
unset IV_C IV_P IV_NV IV_V
}

If you only need to increment through a limited
range, you can just do something like (untested
code):

# Maximum input value: 10
incVar() # varname
{
varName="$1"
set 1 2 3 4 5 6 7 8 9 10 11
eval shift '${'$varName':-0}'
eval $varName=\"$1\"
}


-Wm


Chris F.A. Johnson

unread,
Sep 6, 2005, 12:43:55 PM9/6/05
to

In any POSIX shell (e.g., bash, ksh, and, on many systems, sh):

VAR=$(( $VAR + 1 ))


In a Bourne shell, you can create a string large enough to contain
all the values you will need, and use the positional parameters (so
long as you are using positive integers):

inc()
{
NUMS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23"
__VAR=$1
eval "__VAL=\$$__VAR"
set -- $NUMS
shift $__VAL
eval "$__VAR=\$1"
}

Call the function with the name of the variable, not its value:

$ x=11
$ inc x
$ echo $x
12
$ var=7
$ inc var
$ echo $var
8


--
Chris F.A. Johnson <http://cfaj.freeshell.org>
==================================================================
Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress
<http://www.torfree.net/~chris/books/cfaj/ssr.html>

William Park

unread,
Sep 6, 2005, 2:14:21 PM9/6/05
to

So many ways. In standard Bash shell,
VAR=$((VAR+1))
((VAR++))
If you have a Bash shell with RPN calculator patched in, then
rpn $VAR x++ VAR=x

--
William Park <openge...@yahoo.ca>, Toronto, Canada
ThinFlash: Linux thin-client on USB key (flash) drive
http://home.eol.ca/~parkw/thinflash.html
BashDiff: Super Bash shell
http://freshmeat.net/projects/bashdiff/

Stachu 'Dozzie' K.

unread,
Sep 6, 2005, 3:07:21 PM9/6/05
to
On 06.09.2005, Christophe Gaubert <christoph...@wanadoo.fr> wrote:
> Geezer From The Freezer a écrit :
>> I want to increment a variable without using expr, and using
>> just shell builtins
>>
>> i.e:-
>> VAR=1
>> VAR=`expr $VAR + 1`
>>
>> I've seen it done before, but can't remember how its done using
>> sh or ksh - any pointers please?
>
> With bash, I can do :
> (( var= $var + 1 ))
> # or :
> let "var=var+1"
>
> I don't know if it's bash-specific ?

Probably is bash-, ksh- and zsh-specific (doesn't work under ash).
I don't see any such constructions in SUS. Instead, I see
"var=$(( $var + 1 ))".

--
Feel free to correct my English
Stanislaw Klekot

Christophe Gaubert

unread,
Sep 6, 2005, 3:18:24 PM9/6/05
to
Stachu 'Dozzie' K. a écrit :

> I don't see any such constructions in SUS.

What is "SUS" ?

Mail posté depuis un système libre GNU/Linux

John Kelly

unread,
Sep 6, 2005, 3:30:32 PM9/6/05
to
On Tue, 06 Sep 2005 14:14:21 -0400, William Park
<openge...@yahoo.ca> wrote:

>In standard Bash shell,
> VAR=$((VAR+1))
> ((VAR++))

Since others have shown $VAR inside the double parentheses, it's worth
noting that

VAR=$(($VAR+1))

will work, but

(($VAR++))

will fail. As your example correctly shows, you must use

((VAR++))

without the $ sign. So for consistency, I tend to omit the $ inside
double parentheses.


Lew Pitcher

unread,
Sep 6, 2005, 3:22:53 PM9/6/05
to
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christophe Gaubert wrote:
> Stachu 'Dozzie' K. a écrit :
>
>> I don't see any such constructions in SUS.
>
>
> What is "SUS" ?

"Single Unix Specification"

The official specification of how a Unix(r) system behaves and what
facilities it offers.

http://www.unix.org/version3/online.html


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFDHeyLagVFX4UWr64RAucNAKDRzEYVrwwnYknp5rZXfLAni0PK+QCg7M22
LSV0n//CVR8Fp4QeQ97kJrY=
=DAcx
-----END PGP SIGNATURE-----

Christophe Gaubert

unread,
Sep 6, 2005, 3:37:58 PM9/6/05
to
Lew Pitcher a écrit :

> "Single Unix Specification"
>
> The official specification of how a Unix(r) system behaves and what
> facilities it offers.
>
> http://www.unix.org/version3/online.html

Thanks :)

Stachu 'Dozzie' K.

unread,
Sep 6, 2005, 3:40:10 PM9/6/05
to
On 06.09.2005, Christophe Gaubert <christoph...@wanadoo.fr> wrote:
> Stachu 'Dozzie' K. a écrit :
>> I don't see any such constructions in SUS.
>
> What is "SUS" ?

Single Unix Specification. AFAIK v3 is a POSIX replacement.
http://en.wikipedia.org/wiki/Single_UNIX_Specification
It's freely available at http://www.unix.org/single_unix_specification/
after registration.

Chris F.A. Johnson

unread,
Sep 6, 2005, 3:57:03 PM9/6/05
to

The POSIX arithmetic method is $(( .... )); the variables may or
may not have a $, but must not have it if assignment operatoprs
are used within the parentheses. The parentheses must always be
preceded by the dollar sign to be POSIX compliant.

However, there are otherwise-POSIX-compliant shells which do not
allow variables without the dollar sign. Therefore, I never use it
without them. This means never using assignment operators, and
always have the assignment outside: var=$(( $var + 1 ))

Geezer From The Freezer

unread,
Sep 7, 2005, 6:32:49 AM9/7/05
to
Thanks everyone, I tried that a while back but misplaced
the $ inside the brackets.

Chris F.A. Johnson

unread,
Sep 7, 2005, 12:44:15 PM9/7/05
to
On 2005-09-07, Geezer From The Freezer wrote:
> Thanks everyone, I tried that a while back but misplaced
> the $ inside the brackets.

Tried what?

Please quote enough of the post you are replying to to give the
context of your own post. This is Usenet, not a web forum (though
it is also bastardized on several web sites).

"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Eric van der Meer

unread,
Sep 10, 2005, 7:18:18 AM9/10/05
to
In article <b05f0$431ddc7d$d8fea690$26...@PRIMUS.CA>, William Park
<openge...@yahoo.ca> wrote:

> Geezer From The Freezer <Gee...@freezer.commy> wrote:
> > I want to increment a variable without using expr, and using
> > just shell builtins
> >
> > i.e:-
> > VAR=1
> > VAR=`expr $VAR + 1`
> >
> > I've seen it done before, but can't remember how its done using
> > sh or ksh - any pointers please?
>
> So many ways. In standard Bash shell,
> VAR=$((VAR+1))
> ((VAR++))
> If you have a Bash shell with RPN calculator patched in, then
> rpn $VAR x++ VAR=x

In ksh, if you declare the variable as:

integer VAR

(AKA typeset -i), you can simply use:

VAR=VAR+1

HTH,
Eric

0 new messages