I am trying to compare to build numbers and echo which is greater. Here is a script i wrote
New_Cycle_Num='c4.10'
Old_Cycle_Num='c4.9'
if [ "$New_Cycle_Num" == "$Old_Cycle_Num" ];
then echo 'both are equal'
elif [ "$New_Cycle_Num" "<" "$Old_Cycle_Num" ]];
then echo 'New_Cycle_Num is less than Old_Cycle_Num'
else echo 'New_Cycle_Num is greater than Old_Cycle_Num'
fi
My script gives me ioutput as 'New_Cycle_Num is less than Old_Cycle_Num" instead of last statement. why is c4.10 compared to be less than c4.9? any help to correct this ?? Many thanks!!
You get the result you get because with lexical comparison, comparing the 4th character, "1" appears before "9" in the dictionary (in the same sense that "foobar" would appear before "food", even though "foobar" is longer).
Tools like ls and sort have a "version sorting" option, which will be useful here, albeit somewhat awkward:
New_Cycle_Num='c4.10'
Old_Cycle_Num='c4.9'
if [[ $New_Cycle_Num == $Old_Cycle_Num ]]; then
echo 'equal'
else
before=$(printf "%s\n" "$New_Cycle_Num" "$Old_Cycle_Num")
sorted=$(sort -V <<<"$before")
if [[ $before == $sorted ]]; then
echo 'New_Cycle_Num is less than Old_Cycle_Num'
else
echo 'New_Cycle_Num is greater than Old_Cycle_Num'
fi
fi
New_Cycle_Num is greater than Old_Cycle_Num
I can't think of a great alternative. There might be
echo -e "c4.10\nc4.9" |
perl -MSort::Versions -E '
$a=<>; $b=<>; chomp($a, $b); $c=versioncmp($a,$b);
say "$a is ". ($c==0 ? "equal to" : $c < 0 ? "less than" : "greater than") . " $b"
'
c4.10 is greater than c4.9
But you have to install Sort::Versions from CPAN.
Related
When I choose Option 3 after opening the file it just terminates.
I was trying to use if else function inside section 3 where it ask for new values if there is none stored so that instead of terminating it will ask for values but cant seem to work it out.
#!/bin/bash
while : #This program demonstrate 4 option below
do
clear
echo "Main Menu"
echo "Select any option of your choice"
echo "[1] Show Todays date/time,Files in current directory,home
directory,user id "
echo "[2] Enter a range "
echo "[3] Highest and lowest of the eight random numbers "
echo "[4] Exit/Stop "
echo "==========="
echo -n "Menu choice [1-4]: "
read -r yourch #Choose option out of 4
case $yourch in
1) echo "Today is";date;
echo "Your home directory is:";home;
echo "Your path is :";PWD;
echo "Current Shell";uname;
echo "Your Student ID $USER ID ";
echo "Press a key...";read -r;;
2) echo "Lower value" #Enter the lower value
read -r s1
echo "Higher value" #Enter the higher value
read -r s2
dif=$((s2-s1))
if [ $dif -ne 100 ]
then
echo "Range should be 100"
else #if the differnce is 100 then programe run otherwise terminates
in=$( ("$s2" - "$s1")) #formula for the range
echo "8 random numbers between $s1 and $s2 are :-"
for i in $(seq 1 8)
do
t=$( ($RANDOM % "$in"))
n=$( ("$t" + "$s1"))
echo "$n" #Here we get the random numbers
done
fi
echo "Press a key..."; read -r;;
3) diff=$((s2 - s1)) #Depicts Highest and lowest numbers of the randoms
RANDOM=$$
min=9999
max=-1
for i in $(seq 8)
do
R=$((((RANDOM%diff))+s1))
if [[ "$R" -gt "$max" ]]
then
max=$R
fi
if [[ "$R" -lt "$min" ]]
then
min=$R
fi
done
echo "Biggest number and smallest numbers are $max and $min" #Prints the highest and lowest numbers
echo "press a key...";read -r;;
4)echo " THANK YOU VERY MUCH $ Good Bye"
exit 0;; #Exit command
*)echo "Opps!!! Please select choice 1,2,3,4";
echo "press a key...";read -r;;
esac
done
I would like for it to ask for new values if there is no previous data stored.
I checked your script, to see the problem. It terminates with a division by zero, because s1 and s2 initially are not set. To resolve this, you can use code like
if [ -z "${s1}" ] ;then
read -p "s1 is empty, please enter a number " s1
fi
if [ -z "${s2}" ] ;then
read -p "s2 is empty, please enter a number " s2
fi
-z "..." is true, if the string is empty. The shell doesn't distinguish data types and because I use the doublequotes it is safe to check for an empty string because if s1 is not set, "$s1" results in an empty string.
Btw. "$s1" is logically equivalent to "${s1}", but it is safer to use the curly braces, because there are no ambiguities this way where the variable ends. For example consider the lines:
year=90
echo "I like the music of the $years"
#
echo "I like the music of the ${year}s"
The first echo outputs "I like the music of the" unless variable "years" was set before, while the second outputs "I like the music of the 90s". Without curly braces this would be a bit more inconvenient. Without curly braces sometimes you might run in such ambiguities, without recognizing it easily.
The only way I could find out to compare floats in shell is:
A=12.3
B=12.2
if [ $(bc <<< "$B <= $A") -eq 1 ]
Direct comparison, as far as I know, doesn't happen.
but strangely the following code compares floats without bc:
A=13.7
B=13.2
[[ $A > $B ]] && echo "A is greater than B"
[[ $A < $B ]] && echo "A is less than B"
This returns:
A is greater than B
As far as I know && executes the second command only and only if the first command returns with an exit status zero.
However, as suggested by Pixel Chemist in the comments if we attempt to use negative numbers in the second methods, it doesn't work and gives the opposite results.
Can someone please explain how is the second method working without bc.
newbie to bash:
basically I want to compare the result of $RANDOM to another value which is given by the user through 'read'
code for more info:
echo $RANDOM % 10 + 1 | bc
basically I want an if statement as well to see if the result of that $RANDOM value is equal to something that the user typed in e.g.:
if [ [$RANDOM VALUE] is same as $readinput
#readinput is the thing that was typed before
then
echo "well done you guessed it"
fi
something along the lines of that!!
to summarise
how do i make it so that i can compare a read input value to echo "$RANDOM % 10 + 1 | bc"
think of the program I am making as 'GUESS THE NUMBER!'
all help VERY MUCH APPRECIATED :)
There's no need for bc here -- since you're dealing in integers, native math will do.
printf 'Guess a number: '; read readinput
target=$(( (RANDOM % 10) + 1 )) ## or, less efficiently, target=$(bc <<<"$RANDOM % 10 + 1")
if [ "$readinput" = "$target" ]; then
echo "You correctly guessed $target"
else
echo "Sorry -- you guessed $readinput, but the real value is $target"
fi
The important thing, though, is the test command -- also named [.
test "$readinput" = "$target"
...is exactly the same as...
[ "$readinput" = "$target" ]
...which does the work of comparing two values and exiting with an exit status of 0 (which if will treat as true) should they match, or a nonzero exit status (which if will treat as false) otherwise.
The short answer is to use command substitution to store your randomly generated value, then ask the user for a guess, then compare the two. Here's a very simple example:
#/bin/bash
#Store the random number for comparison later using command substitution IE: $(command) or `command`
random=$(echo "$RANDOM % 10 + 1" | bc)
#Ask the user for their guess and store in variable user_guess
read -r -p "Enter your guess: " user_guess
#Compare the two numbers
if [ "$random" -eq "$user_guess" ]; then
echo "well done you guessed it"
else
echo "sorry, try again"
fi
Perhaps a more robust guessing program would be embedded in a loop so that it would keep asking the user until they got the correct answer. Also you should probably check that the user entered a whole number.
#!/bin/bash
keep_guessing=1
while [ "$keep_guessing" -eq 1 ]; do
#Ask the user for their guess and check that it is a whole number, if not start the loop over.
read -r -p "Enter your guess: " user_guess
[[ ! $user_guess =~ ^[0-9]+$ ]] && { echo "Please enter a number"; continue; }
#Store the random number for comparison later
random=$(echo "$RANDOM % 10 + 1" | bc)
#Compare the two numbers
if [ "$random" -eq "$user_guess" ]; then
echo "well done you guessed it"
keep_guessing=0
else
echo "sorry, try again"
fi
done
I need to check if a variable contains a particular character, for use in an if-conditional in BASH, e.g.:
if [ "①" is in "$numbers" ]
then
echo "Found."
else
echo "Not found."
fi
If $numbers is "These are some numbers 1232", it returns "Not found.", but if "①" is found anywhere in the line, it returns "Found."
I have been using $numbers | grep -c ①, then checking if the output is greater than "0", but it seems there must be a simpler solution.
Right hand side of a comparison can be a pattern:
if [[ $numbers = *①* ]] ; then
As long as it's bash and doesn't need to be posix:
if [[ "$numbers" =~ ① ]]; then
echo "Found"
fi
For a posix solution, use a case statement in place of an if statement:
numbers="①"
case "$numbers" in
*①*) echo "Found it." ;;
*) echo "Not here." ;;
esac
This solution will work under dash which is the default shell (/bin/sh) for scripts under Debian-influenced distributions.
I'm ALL NEW in shell script , hence have a question about how to round up integer.
Here is a line of the code from a script by keke(smstools3 developer)
balance=$(substr "$result" "$balance_prefix" "$balance_suffix")
And my balance is 111.12 , and I wish to round it up.
I tried
balance1=$(substr "$result" "$balance_prefix" "$balance_suffix")
balance=$("%0.f\n" "$balance1")
or
balance1=$(substr "$result" "$balance_prefix" "$balance_suffix")
balance=$(ceil($balance1))
Both refer from some answers after google it , I not even know if the syntax is correct.And of course both example return blank.
Any hints or advice?Thank you.
Edit:
# Check that required words exists:
if [[ "$result" == *${balance_prefix}* ]] && \
[[ "$result" == *${balance_suffix}* ]]
then
# Get the balance and check it:
balance=$(substr "$result" "$balance_prefix" "$balance_suffix")
balance_low=0
if [ $(expr "$balance" + 1 2> /dev/null) ]; then
[ $balance -le $alert_balance ] && balance_low=1
else
echo "Error while parsing an integer: $balance"
fi
else
echo "Error while parsing the answer (balance): $result"
fi
source : http://smstools3.kekekasvi.com/topic.php?id=320
balance=`python -c "from math import ceil; print(ceil($balance1))"`
or
balance=`perl -MPOSIX -e "print ceil($balance1)"`
Using only a minimum of standard tools (perl and python are quite common though):
balance=$(echo "x=${balance1}; scale=0; xx=x/1; if(x>xx) xx+=1; print xx"|bc -l)