for k in {0..49};
do
a=$(($((2*$k))+1));
echo $a;
done
Hi, I need a simplified expression for the third line, maybe one that does not use command substitution.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityUsing arithmetic expansion:
for (( k = 0; k < 50; ++k )); do
a=$(( 2*k + 1 ))
echo "$a"
done
Using the antiquated expr
utility:
for (( k = 0; k < 50; ++k )); do
a=$( expr 2 '*' "$k" + 1 )
echo "$a"
done
Using bc -l
(-l
not actually needed in this case as no math functions are used):
for (( k = 0; k < 50; ++k )); do
a=$( bc -l <<<"2*$k + 1" )
echo "$a"
done
Using bc -l
as a co-process (it acts like a sort of computation service in the background¹):
coproc bc -l
for (( k = 0; k < 50; ++k )); do
printf "2*%d + 1\n" "$k" >&${COPROC[1]}
read -u "${COPROC[0]}" a
echo "$a"
done
kill "$COPROC_PID"
That last one looks (arguably) cleaner in ksh93
:
bc -l |&
bc_pid="$!"
for (( k = 0; k < 50; ++k )); do
print -p "2*$k + 1"
read -p a
print "$a"
done
kill "$bc_pid"
¹ This solved a an issue for me once where I needed to process a large amount of input in a loop. The processing required some floating point computations, but spawning bc
a few times in the loop proved to be exceedingly slow. Yes, I could have solved it in many other ways, but I was bored...
You can use the let
command to force a calculation.
let a="2*k+1"
Note that we don't need $k
in this structure; a simple k
will do the job.
a=2whateverk+1
in the current directory. Worse, if there's a file called a=2+b[$(reboot)]k+1
, that calls the reboot
command. Best is to use ((...))
here (((a = 2 * k + 1))
), or the POSIX syntax: a=$((2 * k + 1))
Jul 30, 2016 at 20:57
The arithmetic expansion you probably need is this:
a=$(( 1+2*k ))
In fact, you do not need to use a variable:
for k in {0..49}; do
echo "$(( 1 + 2*k ))"
done
Or the counting variable could be moved to a for ((…))
loop:
for (( k=0;k<50;k++ )); do
a=$(( 1+2*k ))
printf '%s\n' "$a"
done
And, in that case, the arithmetic expansion could also be moved to inside the for loop:
for (( k=0 ; a=1+2*k , k<50 ; k++)); do
printf '%s\n' "$a"
done
Or, to get all values in an array:
for (( k=0 ; a[k]=1+2*k , k<49 ; k++ )); do :; done
printf '%s\n' "${a[@]}"
But probably the shortest way to avoid any arithmetic expansion is to increment a variable twice:
for (( k=0,a=1 ; k<50 ; k++,a++,a++ )); do
printf '%s\n' "$a"
done
Or, even simpler, just use seq:
seq 1 2 100
bash
and notC
, so remove all;
- unless you write it in a singular line.declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
$(( ... ))
is arithmetic expansion not command substitution.