Shell scripting removing negative integer - shell

How can we remove negative sign from a integer in shell?
Say diff=-234; how can we make diff=234?
I tried with
if [ $diff -lt 0 ]
then
diff=$(expr $diff \* -1)
fi
but this is not working.

You can treat the value as a string or as a number, as you wish. If you treat it as a string, you don't have to do numeric operations:
diff=-234
if [ "$diff" -lt 0 ]
then diff=${diff#-}
fi
echo "$diff"
You could use expr for this too, but that invokes an external process instead of doing it in the shell:
diff=-234
if [ "$diff" -lt 0 ]
then diff=$(expr "$diff" : '^-\(.*\)')
fi
echo "$diff"
Then you can treat it numerically, in many different ways, including:
diff=-234
if [ "$diff" -lt 0 ]
then ((diff *= -1))
fi
echo "$diff"
You can also modify the conditional:
diff=-234
[ "$diff" -lt 0 ] && ((diff *= -1))
echo "$diff"
diff=-234
[[ "$diff" < 0 ]] && ((diff *= -1))
echo "$diff"
diff=-234
(("$diff" < 0)) && ((diff *= -1))
echo "$diff"
diff=-234
((diff < 0)) && ((diff *= -1))
echo "$diff"
diff=-234
[[ "$diff" < 0 ]] && diff=${diff#-}
echo "$diff"
Etcetera.

Using shell arithmetic syntax to determine whether the number is negative and, if so, multiply by -1 to get the positive value.
if ((diff < 0)); then let diff*=-1; fi
Example:
$ diff=-42
$ if ((diff < 0)); then let diff*=-1; fi
$ echo $diff
42

Related

using [[ in bash ifelse scripting gives an error [duplicate]

This question already has answers here:
Difference between sh and Bash
(11 answers)
How to use double or single brackets, parentheses, curly braces
(9 answers)
Closed 3 months ago.
I am doing a simple if else program in bash.
I am trying to understand the difference between [ and (( and [[
this below code works fine
#!/bin/bash
echo "enter a number"
read num
if [ $num -ge 1 -a $num -lt 10 ]
then
echo "A"
elif [ $num -ge 10 -a $num -lt 90 ]
then
echo "B"
elif [ $num -ge 90 -a $num -lt 100 ]
then
echo "C"
else
echo "D"
fi
This code also works fine
#!/bin/bash
echo "enter a number"
read num
if (( num >= 1)) && ((num<10))
then
echo "sam"
elif ((num >= 10)) && ((num < 90 ))
then
echo "ram"
elif ((num >= 90)) && ((num <100))
then
echo "rahim"
else
echo "tara"
fi
but when i try to use [[ there is a problem
#!/bin/bash
echo "enter a number"
read num
if [[ "num" -ge "1" ]] && [[ "num" -lt "10" ]]
then
echo "A"
elif [[ "num" -ge "10" ]] && [[ "num" -lt "90" ]]
then
echo "B"
elif [[ "num" -ge "90" ]] && [[ "num" -lt "100" ]]
then
echo "C"
else
echo "D"
fi
sourav#LAPTOP-HDM6QEG8:~$ sh ./ifelse2.sh
enter a number
50
./ifelse2.sh: 4: [[: not found
./ifelse2.sh: 7: [[: not found
./ifelse2.sh: 10: [[: not found
./ifelse2.sh: 14: echo D: not found
can someone explain this,i tried without double quoting the variable too.

Values of an array not comparing to numbers correctly

Im trying to get an array from grades.txt, and determine what letter grade it should be assigned.
I either get
hw4part2.sh: line 26: [: : integer expression expected
If i use -ge or
hw4part2.sh: line 26: [: : unary operator expected
If i use >=
Below is the code im trying to get working
mapfile -t scores < grades.txt
numOScores=0
numOA=0
numOB=0
numOC=0
numOD=0
numOF=0
DoneWScores=0
A=90
B=80
C=70
D=60
F=59
while [ $DoneWScores -eq 0 ]
do
numOScores=$((numOScores + 1))
if [ "${scores[$numOScores]}" -ge "$A" ]
then
echo "A"
elif [ "${scores[$numOScores]}" -ge "$B" ]
then
echo "B"
elif [ "${scores[$numOScores]}" -ge "$C" ]
then
echo "C"
elif [ "${scores[$numOScores]}" -ge "$D" ]
then
echo "D"
elif [ "${scores[$numOScores]}" -le "$F" ]
then
echo "F"
else
echo "Done/error"
DoneWScores=1
fi
done
If anyone knows what my problem is, that'd be greatly appreciated
Consider this:
#!/usr/bin/env bash
if (( ${BASH_VERSINFO[0]} < 4 )); then
echo "Bash version 4+ is required. This is $BASH_VERSION" >&2
exit 1
fi
letterGrade() {
if (( $1 >= 90 )); then echo A
elif (( $1 >= 80 )); then echo B
elif (( $1 >= 70 )); then echo C
elif (( $1 >= 60 )); then echo D
else echo F
fi
}
declare -A num
while read -r score; do
if [[ $score == +([[:digit:]]) ]]; then
grade=$(letterGrade "$score")
(( num[$grade]++ ))
echo "$grade"
else
printf "invalid score: %q\n" "$score"
fi
done < grades.txt
for grade in "${!num[#]}"; do
echo "$grade: ${num[$grade]}"
done | sort

Bash Syntax Error in conditional statement

I am trying to code a script that will tell the user if a triangle is isosceles, equilateral, or scalene. The error is occuring in line 7 (The elif line)
#!/bin/bash
read -p "Enter a number: " x
read -p "Enter a number: " y
read -p "Enter a number: " z
let "a = x + y + z"
if [ $x -eq $y ] && [ $y -eq $z ]
then echo "EQUILATERAL"
elif [[[ $x -eq $y ] && [ $y != $z ]] || [[ $x -eq $z ] && [ $z != $y ]] || [[ $y -eq $z ] && [ $z != $x ]]]
then echo "ISOSCELES"
elif [ $a -gt 1000 ]
then echo "Cannot equal more than 1000"
fi
I do realize that I could do the same thing with multiple elif lines, but I also have another elif as well and I want to keep it clean. Thanks all!
It seems like you think square brackets in the shell are like parentheses in C-style programming languages. That's not how they work. [ is a synonym for the test command, the condition it introduces ends with ]. And [[ is a special token that introduces a conditional expression, which ends with ]]. You can't mix them up, you can't add additional brackets like [[[, and they don't nest.
The grouping operators in the shell are { ... } and ( ... ); the latter also creates a subshell.
elif ( [[ $x -eq $y ]] && [[ $y != $z ]] ) || ( [[ $x -eq $z ]] && [[ $z != $y ]] ) || ( [[ $y -eq $z ]] && [[ $z != $x ]] )

how to compare current time with two different times along with dayofweek in unix shell script?

How to compare two timestamps along with another condition.
Please find below code as an trial for the work around.
d=$(date +%Y%m%d) #Today
d1=$(date +%b" "%d) #Centre1 col 1 & 2 (MON DD)
ct=$(date +'%H%M%S') #Current Time (HHMM)
t01='013000'
t02='033000'
t03='053000'
t04='073000'
find . -mtime 0 -iname "RBDEXT*.csv" -ls | awk '{printf("%-5s%s\t%-40s%s\t%s\t\n", $8,$9,$11,$10,$7)}' > rbdextmp1.txt
rbdextCO=$(wc -l rbdextmp1.txt | awk '{print $1}')
rbdextIN=$(cat rbdextmp1.txt | grep "inprogress" | wc -l)
touch centre.txt
if [[ [ "$rbdextIN" -eq 0 ] &&
[ [ "$ct" -gt "$t01" ] && [ "$ct" -lt "$t02" ] && [ "$rbdextCO" -eq 1 ] ||
[ "$ct" -gt "$t02" ] && [ "$ct" -lt "$t03" ] && [ "$rbdextCO" -eq 2 ] ||
[ "$ct" -gt "$t03" ] && [ "$ct" -lt "$t04" ] && [ "$rbdextCO" -eq 3 ] ]
]]
then
echo "$d1 RBDEXT.$d.csv($rbdextCO) OK" >> centre.txt
elif [ "$rbdextIN" -ge 1 ]
then
echo "$d1 RBDEXT.$d.csv($rbdextCO) OKBUT" >> centre.txt
else
echo "$d1 RBDEXT.$d.csv($rbdextCO) NOK" >> centre.txt
fi
Could you please help me on this please, Thanks a lot !
I suggest you build up to this slowly.
Start with:
if [ "2" -gt "1" ]
then
echo "Green"
else
echo "Red"
fi
... check that it works. Then add a second clause using &&, resolve any syntax problems, make sure it works. Then replace your hard-coded values with variables. Then populate the variables with output from date. Check that it still works after each step. You'll get there.
Bonus tip -- backticks for command substitution have been frowned upon for some time, because it's easy to make mistakes. Use currentTime=$(date +%H%M%S) instead.
It sounds like this is what you want:
currenttime=$(date +'%H%M%S')
dayofweek=$(date +'%u')
time1='013000'
time2='033000'
time3='053000'
time4='073000'
count=$(wc -l < xxx.txt)
if (( (dayofweek == 1) &&
( ( (currenttime > time1) && (currenttime < time2) && (count == 1) ) ||
( (currenttime > time2) && (currenttime < time3) && (count == 2) ) ||
( (currenttime > time3) && (currenttime < time4) && (count == 3) ) )
))
then
color="GREEN"
else
color="RED"
fi
printf 'GP_GLOBAL_FEED(%s) %s\n' "$count" "$color" |
mailx -s "$color" abcd#mail.com

Comparing 3 integers using bash

Hey so why am I getting a syntax error on my conditionals. I've checked with previous questions online on the use of quotes "" and [[]] and made sure to use both. Also the && symbol in the if statement but I can't seem to get it to work any ideas?
#!/bin/bash
echo Please input integer number 1
read i1
echo Please input integer number 2
read i2
echo Please input integer number 3
read i3
if [[ "$i1" >= "$i2" ]] && [[ "$i1" >= "$i3" ]];then
echo $i1
elif [[ "$i2" >= "$i1" ]] && [[ "$i2" >= "$i3" ]];then
echo $i2
else
echo $i3
fi
It should be -ge instead of >=
Try man test for more information
#!/bin/bash
echo Please input integer number 1
read i1
echo Please input integer number 2
read i2
echo Please input integer number 3
read i3
if [[ "$i1" -ge "$i2" ]] && [[ "$i1" -ge "$i3" ]];then
echo $i1
elif [[ "$i2" -ge "$i1" ]] && [[ "$i2" -ge "$i3" ]];then
echo $i2
else
echo $i3
fi

Resources