Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Why does bash use -lt, -eq
etc for number comparison, and ==, != etc for string comparison ?
Bash syntax has its quirks which make it difficult to write and remember, but this seems completely non-intuitive for a simple use case.
Source : [bash syntax][1]http://www.ibm.com/developerworks/library/l-bash-test/index.html
bash only has one type: strings. More richly typed languages can overload (e.g.) the > operator to perform string comparison or numerical comparison based on the types of the arguments. Lacking anything other than a string type, bash must have separate operators for the different operations. Compare
[[ 9 > 10 ]] # exit status 0; 9 is lexicographically greater than 10
[[ 9 -gt 10 ]] # exit status 1; 9 is not numerically greater than 10
You can, however, use the normal operators for numbers if you use them inside an arithmetic expression, where bash assumes all values are either numbers or variables with numerical values.
(( 9 > 10 )) # exit status 1, 9 is not numerically greater than 10
(( 9 > foo )) # same as [[ 9 -gt $foo ]]
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
The community is reviewing whether to reopen this question as of yesterday.
Improve this question
The code snippet below extracts values from an xml file and store totals for days 1 to 7 and a grand total for the last 7 days - $lsd. The day figures are 6 digit numbers with 3 decimal places. I cannot make the 'awk' function work. Everything I have tried produces either "0.000" or "". Changing the INC operator to simple addition gives similar results
Needless to say, I'm a complete newbie to Bash Arithmetic. Please can somebody tell me where I'm going wrong.
for i in {1..7} ;
do
day=$(grep -oPm1 "(?<=<d00$i>)[^<]+" < data.xml)
printf "%.3f" $day > day$i.txt ;
awk 'BEGIN{lsd += $day}'
done ;
printf "%.3f" $lsd > lsd1.txt
Please can somebody tell me where I'm going wrong.
(...)
awk 'BEGIN{lsd += $day}'
(...)
printf "%.3f" $lsd > lsd1.txt
does suggests that you are promptly ignoring that awk's variables and bash's variables are separate from each other, consider following example
x=10
awk 'BEGIN{x+=1;print x}' emptyfile
echo $x
does output
1
10
Observe that inside awk command x is unset, thus when increment by 1 is request it is assumed to be 0 thus print x does give 1 and awk did not anything to bash's x as shown by line with echo.
(tested in GNU Awk 5.0.1)
This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 4 years ago.
Ok, so I've been working around with some results from speedtest-cli and realised that I had some errors due to the fact that bash doesn't seem to correctly handle the change in digits?
Anyways, here is an example ran directly from the terminal :
ubuntu:~$ l1=9.99
ubuntu:~$ l2=10.44
ubuntu:~$ if [[ (($l2 > $l1)) ]]; then echo "Ok"; fi
ubuntu:~$ if [[ (($l2 < $l1)) ]]; then echo "Not ok"; fi
Not ok
Of course, comparing eg. 10.33 and 11.34 would give the right result.
How does this happen and how can I fix it? Is there another way to achieve this comparison?
Thanks
You're using string comparison, not numeric. Inside double square brackets, parentheses are used just for precedence, so your condition is equivalent to
[[ $l2 < $l1 ]]
To use numeric comparison, use double parentheses without the square ones:
(( l2 < l1 ))
Unfortunately, this wouldn't work either, as bash doesn't support floating point arithmetic, only integer.
You need to use an external tool, e.g.
bc <<< "$l1 < $l2"
bc returns 1 for true and 0 for false.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
Just as the title states, I'm confused about $IFS$(), I saw it in a website which said that $IFS$() can replace the blank space, but I don't know how. Can anyone help me?
By $IFS$() they probably mean they change IFS from default white space, to end of string.
From bash manpages:
IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is ``<space><tab><newline>''.
They mean they do IFS=$() which acts the same as doing IFS=$'\0', declaring that field separator is null character, which marks end of a string.
$() means return the output of command inside parenthesizes, which the is the same as you just pressing Enter key in terminal.
Example:
$ cat test
1 2 3 4 5 6 7
8 9
It will take every number as new variable, because every whitespace (be it single space, tab or new line is considered field separator)
$ for i in $(cat test); do echo $i; done
1
2
3
4
5
6
7
8
9
If we change IFS to $(), output is the same as is in the file:
$ IFS=$();for i in $(cat test); do echo $i; done
1 2 3 4 5 6 7
8 9
Unset IFS and it goes back to looking whitespace as IFS
$ unset IFS
$ for i in $(cat test); do echo $i; done
1
2
3
4
5
6
7
8
9
you can similarly make IFS change to null character with $'\0'
$ IFS=$'\0';for i in $(cat test); do echo $i; done
1 2 3 4 5 6 7
8 9
IFS=$() is basically the same as IFS= or IFS="", you are declaring it equal to empty string so bash looks for end of strings as separators.
This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 4 years ago.
I am trying to write a program that checks whether the number stored in a file (variable n) + 8 is greater or equal to 100. If it is, terminate, else, add 8 and store back in file. However, when I try running it, it says the command in line 4 (if condition) cannot be found. Can someone please explain to me why this isn't working? Thanks.
#!/bin/bash
n=$(cat test.txt)
if [$(($n+8)) -ge 100]
then
echo 'terminated program' > test.txt
else
m=$(($n+3))
echo $m > test.txt
fi
You miss some spaces :
if [$(($n+8)) -ge 100]
->
if [ $(($n+8)) -ge 100 ]
But while using bash, prefer a modern solution, using bash arithmetic :
if (( n+8 >= 100 ))
or even
if ((n+8>=100))
Like #Gordon Davisson said in comments : arithmetic contexts like inside (( )) are one of the few places in bash where spaces aren't critical delimiters.
This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 5 years ago.
Currently i'm writing a script that checks whether an amount is higher than the other.
if [ "324,53" -gt "325,00" ]; then
echo "Amount is higher!"
else
echo "Amount is lower."
fi
Obviously i'm receiving the error: "integer expression expected" when running this. I tried to use sed 's/[^0-9]*//g'` but i need the full number again for further use. Problem is that I don't know the correct way how to do this. Can anybody give some advice?
Bash can't handle floating point numbers. You need to use an external tool, e.g. bc, but you need to use decimal point, not comma:
if (( $(bc <<< '324.53 > 325.00') )) ; then
bc prints 1 when the condition is true, and 0 when it's false. $(...) takes the output of the command, and (( ... )) interpret it as a number, returning false for zero and true for anything else.