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
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.
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.
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.
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
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.