imagine we have n months, here say n=3
I would like to keep adding integer 1, 2, 3 into a shell variable called $test:
so when we do
cat $test
it will return
1 2 3
Any idea?
Just find a solution:
for ((i=1;i<=3; i++));
do
test1="${i}"
test+="$test1 "
done
$ n=3
$ for((i=1; i<=n; i++)) do test="${test} $i"; done
$ echo "$test"
1 2 3
Related
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.)
Why does ...
sum=0; for i in 1 2 3 4; do echo "$i" | sum=$((sum+i)); done; echo $sum
... work as expected in zsh but not in bash? Perhaps because of bash not supporting floating point arithmetic? I also tried ...
sum=0; for i in 1 2 3 4; do echo "$i" | awk '{sum+=$1}'; done; echo $sum
... but that doesn't work in neither (this is on macOS 10.14.2). I found several related questions (such as this or this) but this question still remained.
there is a wrong "|"
sum=0; for i in 1 2 3 4; do echo "$i" ; sum=$((sum+i)); done; echo $sum
1
2
3
4
10
The second example does not work as you are invoking awk every time the loop is repeated so the value of sum is not stored.
Please tell why printing odd numbers in bash script with the following code gives the error:
line 3: {1 % 2 : syntax error: operand expected (error token is "{1 % 2 ")
for i in {1 to 99}
do
rem=$(( $i % 2 ))
if [$rem -neq 0];
then
echo $i
fi
done
This is working example:
for i in {1..99}
do
rem=$(($i % 2))
if [ "$rem" -ne "0" ]; then
echo $i
fi
done
used for loop have a typo in minimum and maximum number, should be {1..99} instead of {1 to 99}
brackets of the if statement needs to be separated with whitespace character on the left and on the right side
Comparision is done with ne instead of neq, see this reference.
As already pointed out, you can use this shell checker if you need some clarification of the error you get.
Not really sure why nobody included it, but this works for me and is simpler than the other 'for' solutions:
for (( i = 1; i < 100; i=i+2 )); do echo $i ; done
To print odd numbers between 1 to 99
seq 1 99 | sed -n 'p;n'
With GNU seq, credit to gniourf-gniourf
seq 1 2 99
Example
$ seq 1 10 | sed -n 'p;n'
1
3
5
7
9
if you reverse it will print even
$ seq 1 10 | sed -n 'n;p'
2
4
6
8
10
One liner:
for odd in {1..99..2}; do echo "${odd}"; done
Or print in a cluster.
for odd in {1..99..2}; do echo -n " ${odd} "; done
Likewise, to print even numbers only:
for even in {2..100..2}; do echo "${even}"; done
OR
for even in {2..100..2}; do echo -n " ${even} "; done
Replace {1 to 99} by {1..99}.
for (( i=1; i<=100; i++ ))
do
((b = $i % 2))
if [ $b -ne 0 ]
then
echo $i
fi
done
for i in {1..99}
do
rem=`expr $i % 2`
if [ $rem == 1 ]
then
echo "$i"
fi
done
for i in {0..49}
do
echo $(($i*2+1))
done
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
I wonder If it is possible to write "for i in {n..k}" loop with a variable.
For example;
for i in {1..5}; do
echo $i
done
This outputs
1
2
3
4
5
On the other hands
var=5
for i in {1..$var}; do
echo $i
done
prints
{1..5}
How can I make second code run as same as first one?
p.s. I know there is lots of way to create a loop by using a variable but I wanted to ask specifically about this syntax.
It is not possible to use variables in the {N..M} syntax. Instead, what you can do is use seq:
$ var=5
$ for i in $(seq 1 $var) ; do echo "$i"; done
1
2
3
4
5
Or...
$ start=3
$ end=8
$ for i in $(seq $start $end) ; do echo $i; done
3
4
5
6
7
8
While seq is fine, it can cause problems if the value of $var is very large, as the entire list of values needs to be generated, which can cause problems if the resulting command line is too long. bash also has a C-style for loop which doesn't explicitly generate the list:
for ((i=1; i<=$var; i++)); do
echo "$i"
done
(This applies to constant sequences as well, since {1..10000000} would also generate a very large list which could overflow the command line.)
You can use eval for this:
$ num=5
$ for i in $(eval echo {1..$num}); do echo $i; done
1
2
3
4
5
Please read drawbacks of eval before using.