Home > Blockchain >  In bash how to use the last argument- and adding all other arguments to array
In bash how to use the last argument- and adding all other arguments to array

Time:12-25

I have a script where the user can add as many arguments as he would like (numbers).

The script will sum all the numbers beside the last number - The last number (argument) is the number that I need to divide by

For example:

./test.sh 2 2 6 5

This will sum the first 3 numbers (2 2 6) and divide the answer by 5 (the last argument)

  1. How can I use the last argument? Echo ????
  2. How can I move loop the first arguments besides the last one – I would like that all 3 arguments will be added to an array and I can loop it
  3. Please note that the number of arguments can be changed

CodePudding user response:

How can I use the last argument? Echo ????

Granting $# > 0, you can use "${!#}".

How can I move loop the first arguments besides the last one – I would like that all 3 arguments will be added to an array and I can loop it

Again granting $# > 0, you can refer to "${@:1:$# - 1}".

Read the Arrays section in the bash manual to know how to properly expand arrays.

I also recommend learning how quoting works and knowing the dangers of unwanted word splitting and globbing.

CodePudding user response:

Shortly (with bashisms)

As this question is tagged and :

Here is a small and efficient script:

#!/bin/bash

addVals=${*: 1 : $# - 1}
declare -i intResult=" ( ${addVals// / } ) / ${@: -1} "
echo $intResult

But there's no loop...

Long answer

How can I use the last argument? Echo ????

You could make your tries in command line:

set -- 2 2 6 5

Then

echo $@
2 2 6 5

echo ${*: 3}
6 5

echo ${*: -1} 
5

echo ${*: 1 : -1} 
bash:  -1: substring expression < 0

echo $#  
4
echo ${*: 1 : $# -1}
2 2 6

Ok, then

someVar=${*: 1 : $# -1}
echo ${someVar// /:SpaceReplacment:}
2:SpaceReplacment:2:SpaceReplacment:6

so

declare -i result
result=" ( ${someVar// / } ) / ${*: -1} "
echo $result
2

How can I move loop the first arguments besides the last one – I would like that all 3 arguments will be added to an array and I can loop it

Still forward, under command line...

someArray=("${@: 1: $# -1 }")

Use declare -p to show $someArray's content:

declare -p someArray
declare -a someArray=([0]="2" [1]="2" [2]="6")

Then

declare -i mySum=0
for i in "${someArray[@]}";do
    mySum =i
done
echo $mySum
10

echo $(( mySum / ${*: -1} ))
2

Please note that the number of arguments can be changed

Please note:

  • Using double quotes allow processing of strings containing spaces:

    set -- foo bar 'foo bar baz'
    echo ${2}
    bar
    echo ${*: $# }
    foo bar baz
    
  • Difference betweeen use of "$@" (array to array) and "$*" (array to string)

    set -- foo bar 'foo bar' 'foo bar baz'
    

    If I take 3 first elements:

    someArray=("${@: 1: $# -1 }")
    declare -p someArray
    declare -a someArray=([0]="foo" [1]="bar" [2]="foo bar")
    

    But

    someArray=("${*: 1: $# -1 }")
    declare -p someArray
    declare -a someArray=([0]="foo bar foo bar")
    
  • Related