Slykin
Slykin

Reputation: 33

Shellscript: Comparing parameters, outputting max and min

Now as I am fairly new to shell scripting and Linux itself, I am quite confused as to why this does not work. An explanation along with the answer would be great help since I really want to learn this. Anyways here is my code:

      #!/bin/bash
      #
      #Script number 7
      #
      while i in $#;
      do
         if [ $i -gt $@ ]; then max=$i; fi
         if [ $i -lt $@ ]; then min=$i; fi
      done
      echo Max is: $max
      echo Min is: $min

What I need to do is obtain a list of parameters then compare them and output the ones with the highest and least value. I feel like I am missing something completely here. Based on my loop I look for the value that is greater than the list and assign it as max. Then I look for the least and assign it as min. Any help is wonderful. Thanks in advance!

Upvotes: 2

Views: 4887

Answers (4)

David W.
David W.

Reputation: 107080

The answer you picked isn't going to do it. If there is no negative number, that won't work. Try that with list as 3, 4, and 5. That will give you that the minimum is zero.

What you need to do is to set both minimum and maximum to the first number in the list, then go through the rest of the numbers to get it:

#! /bin/bash

min=$1
max=$1
shift

for num in $@
do
    [ $num -gt $max ] && max=$num
    [ $num -lt $min ] && min=$num
done

echo "Min = $min  Max = $max"

I set both min and max to the first number in my list. I then use shift to get rid of that number.

Now, I go through each number in my list. The $@ represents the command line arguments. Both $@ and $* represent all of the positional parameters, and either will work in this case.

The

[ $num -gt $max ] && max=$num

statement is similar to

if [ $num -gt $@ ]; then max=$num; fi

which is similar to how you put your if statement on a single line. However, the way I did it is a standard way it's done in BASH. The && is a list operator. If the statement before the && is true, the statement after the && will be executed. Otherwise, the statement after the && won't be executed.

You'll see a similar thing with the || list operator. This is an inverse where the statement after the || is only executed if the statement before is false.

It looks like the special variables were confusing to you:

  • while statement: This will continue to loop as long as statement continues to return a true value. In shell, a true value is zero, and a false value is non-zero.
  • $# is the number of command line parameters with $1 to $x representing each parameter.
  • $@ represents a list of all command line parameters.
  • for var in list: This sets the variable var to each item in the list. This is usually what you want when you parse command line parameters.

Upvotes: 4

Display Name is missing
Display Name is missing

Reputation: 6227

Your syntax is a little off, please see the following example:

#!/bin/bash


List=(-3 1 2 3 4 5);
max=-999999999;
min=999999999;

  for i in ${List[@]}
  do
     if [[ $i -gt $max ]] 
     then 
         max=$i
     fi
     if [ $i -lt $min ] 
     then
        min=$i
     fi
  done

echo Max is: $max
echo Min is: $min

Your output should be:

Max is: 5
Min is: -3

Upvotes: 2

that other guy
that other guy

Reputation: 123570

I'm joining the party.

#!/bin/bash
{ read min; read max; } <<< "$(printf "%s\n" "$@" | sort -n | sed -n '1p;$p')"
echo "Min: $min, Max: $max"

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 204015

This is a job for awk, not shell:

$ cat tst.sh
awk -v argsS="$*" 'BEGIN {

    numArgs = split(argsS,argsA)
    min = max = argsA[1]

    for (idx=2; idx<=numArgs; idx++) {
        arg = argsA[idx]
        min = (arg < min ? arg : min)
        max = (arg > max ? arg : max)
    }

    print "min=",min
    print "max=",max

}'

$ ./tst.sh 3 8 2 9 4
min= 2
max= 9

$ ./tst.sh the quick brown fox jumped        
min= brown
max= the

$ ./tst.sh 3                         
min= 3
max= 3

$ ./tst.sh -2 -5 -1
min= -5
max= -1

Notice that it works with strings as well as numbers, it can be trivially customized to print "NaN' or whatever you like if invalid input is provided, and it won't incorrectly print "0" as the max value when all of your input numbers are negative or zero as the min when you only provide 1 positive number (try both of those test cases on the shell solution you selected as the right answer).

Upvotes: 0

Related Questions