linux bash script error - bash

when I try to run this script
for ((i=1; i<=5; i++))
do
for ((j=1; j<=5; j++))
do
echo –n $i
done
echo " "
done
I get this error:
syntax error near unexpected token '(('
for ((j=1; j<=5; j++))"

It appears you're running this with an interpreter that is not bash. I've indented your code, but it worked just fine without indentation too.
$ cat test.bash
for ((i=1; i<=5; i++))
do
for ((j=1; j<=5; j++))
do
echo –n $i
done
echo " "
done
$ /bin/sh test.bash
/tmp/test.bash: 1: Syntax error: Bad for loop variable
$ echo $BASH_VERSION
5.0.11(1)-release
$ bash test.bash
–n 1
–n 1
–n 1
–n 1
–n 1
–n 2
–n 2
…
As you can see, echo -n is not reliable. Change that line to printf %s $i to resolve that and your output will become:
11111
22222
33333
44444
55555
If you are invoking it with bash, perhaps your bash version is too old? You can use for i in {1..5} for something more compatible (but not valid POSIX) or you could use for i in 1 2 3 4 5 for full POSIX compatibility. If you have GNU coreutils, you could do for i in $(seq 5) instead (see man seq).
To better approach your intended logic, you could also consider a while loop:
i=0
while [ $((++i)) -le 5 ]
do
j=0
while [ $((++j)) -le 5 ]
do
printf %s $i
done
echo " "
done
This initializes i to zero before a while loop, then increments it in the test condition when comparing it to five; the first loop's first iteration increments i to 1, finds that it is indeed less than or equal (-le) to 5, and therefore continues.
(I'm using a $((…)) arithmetic expression and ++i inside it since the more common i++ would return the value of i before it is incremented while ++i returns the value of i after it is incremented.)

Related

Sum of integer variables bash script

How can I do the sum of integers with bash script I read some variables with a for and I need to do the sum.
I have written the code like this:
Read N
Sum=0
for ((i=1;i<=N;i++))
do
read number
sum=sum+number
done
echo $sum
Use the arithmetic command ((...)):
#! /bin/bash
read n
sum=0
for ((i=1; i<=n; i++)) ; do
read number
((sum+=number))
done
echo $sum
#!/bin/bash
echo "Enter number:"
read N
re='^[0-9]+$'
if ! [[ ${N} =~ ${re} ]]
then
echo "Error. It's not a number"
exit 1
fi
Sum=0
for ((i=1;i<=N;i++))
do
sum=$((${sum} + ${i}))
done
echo "${sum}"
Well, not a straight bash solution, but you can also use seq and datamash (https://www.gnu.org/software/datamash/):
#!/bin/bash
read N
seq 1 $N | datamash sum 1
It is really simple (and it has its limitations), but it works. You can use other options on seq for increments different than 1 and so on.
It is also possible to declare a variable as an integer with declare -i. Any assignment to that variable is then evaluated as an arithmetic expression:
#!/bin/bash
declare -i sum=0
read -p "Enter n: " n
for ((i=1; i<=n; i++)) ; do
read -p "Enter number #$i: " number
sum+=number #sum=sum+number would also work
done
echo "Sum: $sum"
See Bash Reference Manual for more information. Using arithmetic command ((...)) is preferred, see choroba's answer.
$ declare -i var1=1
$ var2=1
$ var1+=5
$ echo "$var1"
6
$ var2+=5
$ echo "$var2"
15
This can be a tad confusing as += behaves differently depending on the variable's attributes. It's therefore better to explicitly use ((...)) for arithmetic operations.

Form a sequence of integers at specified interval in bash

I create a sequence with interval 1 using {0..4} syntax alright:
$ for i in {0..4}; do echo $i; done
0
1
2
3
4
However, when I set interval explicitly at 2 using conventional syntax {0..4..2}, it doesn't work:
$ for i in {0..4..2}; do echo $i; done
{0..4..2}
And the expected output should be:
0
2
4
My bash version:
$ echo ${BASH_VERSION}
3.2.25(1)-release
Any feedback is appreciated!
You could use the syntax:
$ for ((i=0; i<=4; i+=2)); do echo $i; done
$ for i in `seq 0 2 4`; do echo $i; done

Increment variable value by 1 (shell programming)

I can't seem to be able to increase the variable value by 1. I have looked at tutorialspoint's Unix / Linux Shell Programming tutorial but it only shows how to add together two variables.
I have tried the following methods but they don't work:
i=0
$i=$i+1 # doesn't work: command not found
echo "$i"
$i='expr $i+1' # doesn't work: command not found
echo "$i"
$i++ # doesn't work*, command not found
echo "$i"
How do I increment the value of a variable by 1?
You can use an arithmetic expansion like so:
i=$((i+1))
or declare i as an integer variable and use the += operator for incrementing its value.
declare -i i=0
i+=1
or use the (( construct.
((i++))
The way to use expr:
i=0
i=`expr $i + 1`
The way to use i++ (unless you're running with -e/-o errexit):
((i++)); echo $i;
Tested in gnu bash.
you can use bc as it can also do floats
var=$(echo "1+2"|bc)
These are the methods I know:
ichramm#NOTPARALLEL ~$ i=10; echo $i;
10
ichramm#NOTPARALLEL ~$ ((i+=1)); echo $i;
11
ichramm#NOTPARALLEL ~$ ((i=i+1)); echo $i;
12
ichramm#NOTPARALLEL ~$ i=`expr $i + 1`; echo $i;
13
Note the spaces in the last example, also note that's the only one that uses $i.

Loop in UNIX is not working

Please tell me what is wrong with the UNIX code below.
#!/bin/ksh
p=10
for i in $p
do
echo $i
done
i am expecting output as
1
2
3
.
.
.
but the output am getting is just 10
I need for loop not while loop.
in ksh
#!/bin/ksh
p=10
i=1
while ((i<=p)); do
echo $i
i=$((i+1))
done
or
#!/bin/ksh
# with for you can only do this
for i in 1 2 3 4 5 6 7 8 9 10; do
echo $i
done
in bash it works as expected
#!/bin/bash
p=10
for (( i=1; i<=p; i++ )); do
echo $i
done
there is a Linux command seqthat can be used for both ksh and bash. But it is a Linux command. So this will not work on Solaris or other Unix systems that don't have the progrtam seq installed.
# on Linux, bash or ksh
p=10
for i in $(seq $p); do
echo $i
done
The following uses only shell built-ins and therefore will work for all bash installations (e.g. on Solaris) but not for ksh
#!/bin/bash
p=10
for i in `eval echo {1..$p}`; do
echo $i
done
This complicated construct is necessary because of brace expansion occurrs before variable expansion
You have to assign a range. Otherwise the loop can't work. This should do it:
#!/bin/ksh
p=10
for i in {0..$p}
do
echo $i
done
#fedorqui: You are right, I absolutely missed that. When I do stuff like this in Bash (I don't know if it's the same for KornShell), I go like:
for ((i=0; i<$p; i++))
in UNIX KSH
#!/bin/ksh
while [ ${i:=1} -le 10 ]
do
echo "$i"
let i+=1
done

Bourne Shell For i in (seq)

I want to write a loop in Bourne shell which iterates a specific set of numbers. Normally I would use seq:
for i in `seq 1 10 15 20`
#do stuff
loop
But seemingly on this Solaris box seq does not exist. Can anyone help by providing another solution to iterating a list of numbers?
try
for i in 1 10 15 20
do
echo "do something with $i"
done
else if you have recent Solaris, there is bash 3 at least. for example this give range from 1 to 10 and 15 to 20
for i in {1..10} {15..20}
do
echo "$i"
done
OR use tool like nawk
for i in `nawk 'BEGIN{ for(i=1;i<=10;i++) print i}'`
do
echo $i
done
OR even the while loop
while [ "$s" -lt 10 ]; do s=`echo $s+1|bc`; echo $s; done
You can emulate seq with dc:
For instance:
seq 0 5 120
is rewritten as:
dc -e '0 5 120 1+stsisb[pli+dlt>a]salblax'
Another variation using bc:
for i in $(echo "for (i=0;i<=3;i++) i"|bc); do echo "$i"; done
For the Bourne shell, you'll probably have to use backticks, but avoid them if you can:
for i in `echo "for (i=0;i<=3;i++) i"|bc`; do echo "$i"; done
#!/bin/sh
for i in $(seq 1 10); do
echo $i
done
I find that this works, albeit ugly as sin:
for i in `echo X \n Y \n Z ` ...
for i in `seq 1 5 20`; do echo $i; done
Result:
5
10
15
20
$ man seq
SEQ(1) User Commands SEQ(1)
NAME
seq - print a sequence of numbers
SYNOPSIS
seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST

Resources