Ubuntu bash –eq: binary operator expected - nested for loop - bash

I am trying to make Linux bash for my study homework and I think everything is fine(checked many resources), but still error is showing up (–eq: binary operator expected ). What's wrong in my example?
for (( i=1; i <= 3; i++)) ### Outer for loop ###
do
for (( j=1; j <= 3; j++)) ### Inner for loop ###
do
tot=$(expr $i + $j)
echo „tot value: $tot”
tmp=$(expr $tot % 2)
echo „tmp value: $tmp”
if [ $tmp –eq 0 ]; then
echo –e –n „\033[47m ”
else
echo –e –n „\033[40m”
fi
done
echo –e –n „\033[40m” #### set back background colour to black
echo „” #### print the new line ####
done

You are using the wrong character in –eq. It should be a minus (-), not a hyphen (–). The same goes for the hyphen you use on the echo lines.
Also consider using bash's built-in arithmetic expansion instead of expr and test:
#!/bin/bash
for (( i=1; i <= 3; i++)) ### Outer for loop ###
do
for (( j=1; j <= 3; j++)) ### Inner for loop ###
do
(( tot = i + j ))
echo "tot value: $tot"
(( tmp = tot % 2 ))
echo "tmp value: $tmp"
if (( tmp == 0 )); then
echo -e -n "\033[47m "
else
echo -e -n "\033[40m"
fi
done
echo -e "\033[40m" #### set back background colour to black
done

Related

loop in bash does not perform integer comparison properly

I have below code
i=0
for s in / - \\ \|
do
printf "\rWaiting for application start to finish $i $s"
sleep 1
((i++))
if [[ $i -gt 30 ]]
then
break
fi
done
The loop always ends after 3 iterations. Any reason as why?
This might be what you are looking for:
#!/bin/bash
a=('/' '-' '\' '|')
for ((i = 0; i < 30; ++i)); do
printf '\rWaiting for application start to finish %d %s' \
"$i" "${a[i%4]}"
sleep 1
done
echo
My mistake. The for loop which has three arguments is exiting instead of the if condition failing.

How to increase tabs count based on for loop index in shell script

Following is my for loop
array=( one two three )
for (( i=0;i<${#array[#]};i++ ))
do
echo -e "\t${array[$i]}"
done
with this script I'm getting the output as
#current output
one
two
three
but my requirement is to increase tabs count based on index of for loop.
#required output
one
two
three
can anyone suggest how to achieve this?
Use an inner loop:
for (( i=0; i < ${#array[#]}; ++i )) ; do
for (( j=0; j<=i; ++j )) ; do
printf '\t'
done
echo "${array[$i]}"
done
or accumulate the tabs in a variable:
for (( i=0; i < ${#array[#]}; ++i )) ; do
t+=$'\t'
echo "$t${array[$i]}"
done
Alternatively, use Perl which has the repetition operator:
perl -E 'say "\t" x ++$i, $_ for #ARGV' "${array[#]}"
try
#!/bin/bash
array=( one two three )
for (( i=0;i<${#array[#]};i++ ))
do
printf %"${i}"s |tr " " "\t"
echo -e "\t${array[$i]}"
done
Demo :
$./test.ksh
one
two
three
$cat test.ksh
#!/bin/bash
array=( one two three )
for (( i=0;i<${#array[#]};i++ ))
do
printf %"${i}"s |tr " " "\t"
echo -e "\t${array[$i]}"
done
$
Explanation :
printf %"${i}"s --> will print space i times.

cannot create triangle in shell script with for loop

I am quite new in shell script and trying to make some practice. What I want to do is to get an input from the user and create a triangle by using for loop. For example; if the user types 4 as input then the targeted triangle will be;
1
2
2
3
3
3
4
4
4
4
Here is my code:
num=4 ##Assume num is given by user##
for ((i=1; i<=$num; i++))
do
for ((j=1; j<=i; j++))
do
echo $i
done
echo " "
done
Output:
1
22
333
4444
Is it something related with 'new line' thing? How can I fix it?
By the way, I am using an online shell terminal.
Thank you very much.
echo $i prints the value behind the i variable and a newline. You want to print a newline after all the numbers. Use -n switch.
num=4 ##Assume num is given by user##
for ((i = 1; i <= num; i++))
do
for ((j = 1; j <= i; j++))
do
echo -n "$i "
done
echo
echo
done
Or printf:
num=4 ##Assume num is given by user##
for ((i = 1; i <= num; i++))
do
for ((j = 1; j <= i; j++))
do
printf "%s " "$i"
done
printf "\n\n"
done
Remember to qoute your variables (echo "$i" not echo $i)
No need to use $num inside (( .. )). All names are expanded automagically.
#edit
On revisiting the question I came up with the following oneliner with the same functionality:
num=4
seq 1 "$num" | xargs -n1 seq -s ' ' 1
seq 1 "$num" generates numbers 1 2 .... $num separated by newlines
Then for each number xargs runs seq -s ' ' 1 <number> generating 1 .. number for each number separated by spaces
You can insert double newlines with | sed 's/$/\n/' if needed.

How to process value from for loop in shell

I have to a perform logic like this.
I have a array.
expression for this in shell
[(first no + arrlen) - ( index +1 ) - ge 10 ]
I have code this like this but it's not working
#!/bin/bash
array=(4 5 6 7 8 9)
for i in ${array[#]}
do
echo $i
done
echo "${#array[#]}"
l=${#array[#]}
count=0
for (( i=0; i < ${#array[#]}; i++ ))
do
if [ ($(`expr $i + $l`) - $(`expr ${!array[#]} + 1`)) -ge 10 ]
then
count=`expr $count + 1`
else
echo
fi
done
Your code could look like this:
#!/bin/bash
array=(4 5 6 7 8 9)
for i in "${array[#]}"; do
echo "$i"
done
length=${#array[#]}
first=${array[0]}
count=0
for (( i=0; i < length; i++ )); do
if (( (first + length) - (i + 1) >= 10 )); then
((count++))
else
echo "something"
fi
done
Don't use expr, use (( )) for arithmetic expressions
Quote expansions: "$i", "${array[#]}", ...
${!array[#]} expands to ALL indexes of your array, not the current index

Bash script can't figure out how to concatenating white spaces

I want to center a word in X spaces so I wrote this function:
function center {
str=$1
M=$2
N=${#str}
if (( N >= M )); then
echo $str
exit
fi
P=$((M-N))
HP=$((P/2))
left=""
right=""
for i in [1..HP]; do :
left=" $left"
right=" $right"
done
if (( (P-2*HP) == 1 )); then
right=" "$right""
fi
echo "HP is $HP"
echo "Right is |"${right}"|"
echo "Left is |$left|"
echo "str is |$str|"
res=$right$str$left
echo "$res"
}
Problem is not matter what I do can't get right or left to hold on to more than one whitespace. I have tried the suggestions on other answers but I can't seem to make them work. Please help.
Try this (after some variable quoting and some other fixes):
function center {
str=$1
M=$2
N=${#str}
if (( N >= M )); then
echo "$str"
exit
fi
(( P=M-N ))
(( HP=P/2 ))
left=$(printf '%*s' "$HP" "")
right=$left
(( (P-2*HP) == 1 )) && right=" "$right""
echo "HP is $HP"
echo "Right is |${right}|"
echo "Left is |$left|"
echo "str is |$str|"
res="$right$str$left"
echo "$res"
}
The for i in [1..HP] can not work.
A printf '%*s' "$HP" "" is a more idiomatic way to get $HP spaces.
Is better to build one variable $left and copy it to $right than to build the two.

Resources