Hi there, new to this forum and I recently encounter this problem:
I tried to use if-elif loop in a while-read loop, something like this:
#!/bin/bash
while read myline1 myline2
do
if [ '$myline1 > '$myline2' ]; then
echo "Successful!"
elif [ '$myline1 < '$myline2' ]; then
echo "Failed"
fi
done < $1
Input file looks like this:
200 100
100 200
But the results that I got was:
Successful!
Successful!
It doesn't seems to read the elif condition. Can anyone help?
#!/bin/bash
while read myline1 myline2
do
if [ '$myline1' > '$myline2' ]; then
echo "Successful!"
elif [ '$myline1' < '$myline2' ]; then
echo "Failed"
fi
done < $1
1) Doublequote your variables inside the tests; single quotes prevent variable expansion (and, btw, one quote is missing).
2) use -lt and -gt for numerical comparison; < and > do a string comparison.
You're using the wrong quotes and they aren't matched. And the < and > operators don't exist in the test utility; you're performing redirections in the operands given to test. Try:
#!/bin/bash
while read myline1 myline2
do
if [ "$myline1" -gt "$myline2" ]; then
echo "Successful!"
elif [ "$myline1" -lt "$myline2" ]; then
echo "Failed"
fi
done < $1
According to the standards, you can't with test... and [ ... ] ,
but in [[ ... ]] , < and > are string comparison operators. The -lt and -gt operators perform numeric comparisons in all three forms of these testing methods.
In bash, the < and > are string comparisons in test ... and [ ... ]. In ksh, the < and > will be treated as redirection operators, not string comparisons. I.e., in ksh:
if [ 100 > 200 ]
then echo gt
else echo not gt
fi
will print gt because 100 is not an empty string and will create a file named 200 because > is a redirection operator. But in bash, this same code will print not gt and will not create a file. Both of these behaviors conform to the standards because the standards don't specify any meaning for < and > in these two cases.
=================
I take part of this back. Despite what the bash man page says, at least on Mac OS X, bash and ksh both treat < and > as redirection operators in test and [.
$ if [[ "b" -gt "a" ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ "b" > "a" ]]; then echo "gt"; else echo "not gt"; fi
gt
$ if [[ "a" -gt "b" ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ "a" > "b" ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ a -gt b ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ a > b ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ b -gt a ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ b > a ]]; then echo "gt"; else echo "not gt"; fi
gt
For numeric operation -
$ if [[ "1" -gt "2" ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ "1" > "2" ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ "2" -gt "1" ]]; then echo "gt"; else echo "not gt"; fi
gt
$ if [[ "2" > "1" ]]; then echo "gt"; else echo "not gt"; fi
gt
$ if [[ 1 -gt 2 ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ 1 > 2 ]]; then echo "gt"; else echo "not gt"; fi
not gt
$ if [[ 2 -gt 1 ]]; then echo "gt"; else echo "not gt"; fi
gt
$ if [[ 2 > 1 ]]; then echo "gt"; else echo "not gt"; fi
gt
From this i came to conclusion that -
1) Never use -gt and -lt for string comparison.
2) Use > and < for string comparison and -gt and -lt for numeric comparison..
3) String and numbers are compared in sorted order as
Number - 1 - 9 ( like 9 is greater than 1)
String - A,B,C...Z, a,b,c,....z ( like z is greater than a)
21 interpreted as a string compares less than 3, while as an integer, it compares greater. This is valid for bash; maybe someone can comment on other shells.
That's good one.. it clears useless use of < and > while numeric comparison.. removed from numeric comparison...
As explained in my previous post < and > signs treats as string so they compare each digit by digit. such as..
$ [[ 211 > 12 ]] && echo gt || echo lt # Here it compares 2 with 1 so 2 is greater than 1 as per sort pattern so gt.
gt
$ [[ 211 > 32 ]] && echo gt || echo lt #Here it compares 2 with 3 so 3 is greater than 2 as per sort pattern so lt.
lt