How do I create a bash script that sums any number of command line arguments?
How would I create a bash script that the user can use to sum any amount of command line arguments? For example, say my script is called sum:
sum 3
3
sum 3 5
8
sum 9 8 21
38
And so on.. I realize that I will have to loop through the command line arguments and increment them to the total, but I am not really sure how to do that. I am not sure how to reference say the 2nd command line argument to a specific variable or how to get the number of total command line arguments.
bash shell-script arithmetic
add a comment |
How would I create a bash script that the user can use to sum any amount of command line arguments? For example, say my script is called sum:
sum 3
3
sum 3 5
8
sum 9 8 21
38
And so on.. I realize that I will have to loop through the command line arguments and increment them to the total, but I am not really sure how to do that. I am not sure how to reference say the 2nd command line argument to a specific variable or how to get the number of total command line arguments.
bash shell-script arithmetic
The nativebash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such asawk
,python
,dc
,bc
orperl
. See @rici's answer.
– NVRAM
Nov 5 '13 at 17:12
add a comment |
How would I create a bash script that the user can use to sum any amount of command line arguments? For example, say my script is called sum:
sum 3
3
sum 3 5
8
sum 9 8 21
38
And so on.. I realize that I will have to loop through the command line arguments and increment them to the total, but I am not really sure how to do that. I am not sure how to reference say the 2nd command line argument to a specific variable or how to get the number of total command line arguments.
bash shell-script arithmetic
How would I create a bash script that the user can use to sum any amount of command line arguments? For example, say my script is called sum:
sum 3
3
sum 3 5
8
sum 9 8 21
38
And so on.. I realize that I will have to loop through the command line arguments and increment them to the total, but I am not really sure how to do that. I am not sure how to reference say the 2nd command line argument to a specific variable or how to get the number of total command line arguments.
bash shell-script arithmetic
bash shell-script arithmetic
edited Nov 5 '13 at 23:16
Gilles
542k12810991616
542k12810991616
asked Nov 5 '13 at 6:26
JohnJohn
93991924
93991924
The nativebash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such asawk
,python
,dc
,bc
orperl
. See @rici's answer.
– NVRAM
Nov 5 '13 at 17:12
add a comment |
The nativebash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such asawk
,python
,dc
,bc
orperl
. See @rici's answer.
– NVRAM
Nov 5 '13 at 17:12
The native
bash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such as awk
, python
, dc
, bc
or perl
. See @rici's answer.– NVRAM
Nov 5 '13 at 17:12
The native
bash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such as awk
, python
, dc
, bc
or perl
. See @rici's answer.– NVRAM
Nov 5 '13 at 17:12
add a comment |
3 Answers
3
active
oldest
votes
No need for bash
, plain sh
will do as well:
#! /bin/sh -
IFS=+; echo "$(($*))"
$*
in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS
(or space if $IFS
is unset or nothing if $IFS
is empty). $((...))
is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)
If you need floating point support, that's where you'll need a different shell like ksh93
or zsh
(not bash
as bash
only supports integer arithmetic), though you could also use awk
:
#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}
That will use double
type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).
Some awk
implementations like GNU awk
when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data
, it understands octals and hexadecimals:
$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such asIFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
add a comment |
A non-looping variant:
{ printf %d+ "$@"; echo 0; } | bc
Example
Put the above in a script file, sum
.
#!/bin/bash
{ printf %d+ "$@"; echo 0; } | bc
Run it like so:
$ ./sum 4
4
$ ./sum 4 4 5
13
add a comment |
You can use the following bash function:
sum() {
local sum=0
for arg in "$@"; do
(( sum += arg ))
done
echo $sum
}
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
$#
is the number of args
– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
@John$1
is the first argument,$2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…
– Radu Rădeanu
Nov 5 '13 at 8:04
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments withfirst=$1;shift
– icarus
Nov 19 '16 at 17:45
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98907%2fhow-do-i-create-a-bash-script-that-sums-any-number-of-command-line-arguments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
No need for bash
, plain sh
will do as well:
#! /bin/sh -
IFS=+; echo "$(($*))"
$*
in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS
(or space if $IFS
is unset or nothing if $IFS
is empty). $((...))
is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)
If you need floating point support, that's where you'll need a different shell like ksh93
or zsh
(not bash
as bash
only supports integer arithmetic), though you could also use awk
:
#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}
That will use double
type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).
Some awk
implementations like GNU awk
when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data
, it understands octals and hexadecimals:
$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such asIFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
add a comment |
No need for bash
, plain sh
will do as well:
#! /bin/sh -
IFS=+; echo "$(($*))"
$*
in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS
(or space if $IFS
is unset or nothing if $IFS
is empty). $((...))
is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)
If you need floating point support, that's where you'll need a different shell like ksh93
or zsh
(not bash
as bash
only supports integer arithmetic), though you could also use awk
:
#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}
That will use double
type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).
Some awk
implementations like GNU awk
when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data
, it understands octals and hexadecimals:
$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such asIFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
add a comment |
No need for bash
, plain sh
will do as well:
#! /bin/sh -
IFS=+; echo "$(($*))"
$*
in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS
(or space if $IFS
is unset or nothing if $IFS
is empty). $((...))
is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)
If you need floating point support, that's where you'll need a different shell like ksh93
or zsh
(not bash
as bash
only supports integer arithmetic), though you could also use awk
:
#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}
That will use double
type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).
Some awk
implementations like GNU awk
when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data
, it understands octals and hexadecimals:
$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8
No need for bash
, plain sh
will do as well:
#! /bin/sh -
IFS=+; echo "$(($*))"
$*
in POSIX shells, expands to the list of positional parameters (in this case, the arguments to the script) separated by the first character of $IFS
(or space if $IFS
is unset or nothing if $IFS
is empty). $((...))
is the shell internal arithmetic expansion operator (note that it supports decimal, octal and hexadecimal numbers)
If you need floating point support, that's where you'll need a different shell like ksh93
or zsh
(not bash
as bash
only supports integer arithmetic), though you could also use awk
:
#! /usr/bin/awk -f
BEGIN {t=0; for (i in ARGV) t+=ARGV[i]; print t}
That will use double
type numbers as implemented by your system. The input numbers must be decimal floating point or engineering notation in the English style (floating point delimiter is the period character regardless of the locale).
Some awk
implementations like GNU awk
when POSIXLY_CORRECT is in the environment also support hexadecimals including with binary exponent notations. Or with --non-decimal-data
, it understands octals and hexadecimals:
$ POSIXLY_CORRECT=1 ./sum 0xap3 0xa
90 # (0xa * 2^3) + 0xa
$ awk --non-decimal-data -f ./sum 010
8
edited 7 mins ago
answered Nov 5 '13 at 9:51
Stéphane ChazelasStéphane Chazelas
310k57584945
310k57584945
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such asIFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
add a comment |
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such asIFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such as
IFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
clever. But I really hope you are not confusing him ^^ It seems he's learning shell scripting basics, and you throw him IFS manipulation ^^ It's always good to know, but probably a bit too early for him... Or provide explanations such as
IFS=+ means afterward the "$*" will expand to "all the arguments separated by a '+'", hence the $((computation)) will be replaced with the sum of all arguments
– Olivier Dulac
Nov 5 '13 at 10:13
add a comment |
A non-looping variant:
{ printf %d+ "$@"; echo 0; } | bc
Example
Put the above in a script file, sum
.
#!/bin/bash
{ printf %d+ "$@"; echo 0; } | bc
Run it like so:
$ ./sum 4
4
$ ./sum 4 4 5
13
add a comment |
A non-looping variant:
{ printf %d+ "$@"; echo 0; } | bc
Example
Put the above in a script file, sum
.
#!/bin/bash
{ printf %d+ "$@"; echo 0; } | bc
Run it like so:
$ ./sum 4
4
$ ./sum 4 4 5
13
add a comment |
A non-looping variant:
{ printf %d+ "$@"; echo 0; } | bc
Example
Put the above in a script file, sum
.
#!/bin/bash
{ printf %d+ "$@"; echo 0; } | bc
Run it like so:
$ ./sum 4
4
$ ./sum 4 4 5
13
A non-looping variant:
{ printf %d+ "$@"; echo 0; } | bc
Example
Put the above in a script file, sum
.
#!/bin/bash
{ printf %d+ "$@"; echo 0; } | bc
Run it like so:
$ ./sum 4
4
$ ./sum 4 4 5
13
edited Nov 5 '13 at 8:25
slm♦
254k71535687
254k71535687
answered Nov 5 '13 at 7:25
ricirici
7,6072632
7,6072632
add a comment |
add a comment |
You can use the following bash function:
sum() {
local sum=0
for arg in "$@"; do
(( sum += arg ))
done
echo $sum
}
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
$#
is the number of args
– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
@John$1
is the first argument,$2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…
– Radu Rădeanu
Nov 5 '13 at 8:04
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments withfirst=$1;shift
– icarus
Nov 19 '16 at 17:45
add a comment |
You can use the following bash function:
sum() {
local sum=0
for arg in "$@"; do
(( sum += arg ))
done
echo $sum
}
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
$#
is the number of args
– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
@John$1
is the first argument,$2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…
– Radu Rădeanu
Nov 5 '13 at 8:04
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments withfirst=$1;shift
– icarus
Nov 19 '16 at 17:45
add a comment |
You can use the following bash function:
sum() {
local sum=0
for arg in "$@"; do
(( sum += arg ))
done
echo $sum
}
You can use the following bash function:
sum() {
local sum=0
for arg in "$@"; do
(( sum += arg ))
done
echo $sum
}
answered Nov 5 '13 at 6:46
Radu RădeanuRadu Rădeanu
1,04311239
1,04311239
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
$#
is the number of args
– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
@John$1
is the first argument,$2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…
– Radu Rădeanu
Nov 5 '13 at 8:04
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments withfirst=$1;shift
– icarus
Nov 19 '16 at 17:45
add a comment |
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
$#
is the number of args
– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
@John$1
is the first argument,$2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…
– Radu Rădeanu
Nov 5 '13 at 8:04
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments withfirst=$1;shift
– icarus
Nov 19 '16 at 17:45
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
As a side question, is there a way to determine how many args are in the command line without looping?
– John
Nov 5 '13 at 7:13
4
4
$#
is the number of args– rici
Nov 5 '13 at 7:19
$#
is the number of args– rici
Nov 5 '13 at 7:19
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
Thank you, perfect. One last question I forgot to clarify.. is there any way I can detect if it is like the very first argument? So say it is the very first argument, I can do something special with it. For example, as a random example, if the very first argument is a 7, I echo that the very first argument is a 7.
– John
Nov 5 '13 at 7:47
2
2
@John
$1
is the first argument, $2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…– Radu Rădeanu
Nov 5 '13 at 8:04
@John
$1
is the first argument, $2
is the second argument, and so on. The variable $0 is the script's name. The total number of arguments is stored in $#. The variables $@ and $* return all the arguments. See also: how-to.wikia.com/wiki/…– Radu Rădeanu
Nov 5 '13 at 8:04
1
1
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with
first=$1;shift
– icarus
Nov 19 '16 at 17:45
@John typically if you want to process the first argument differently you first copy it to something else and then shift all the rest of the arguments with
first=$1;shift
– icarus
Nov 19 '16 at 17:45
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f98907%2fhow-do-i-create-a-bash-script-that-sums-any-number-of-command-line-arguments%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The native
bash
feature won't handle floating point values (eg: 3.5). For that you'd need to use a program such asawk
,python
,dc
,bc
orperl
. See @rici's answer.– NVRAM
Nov 5 '13 at 17:12