'How to write a single line shell script with a while loop and if statement
I am trying to figure out the syntax for having a while loop and an if statement that checks for more than one condition, in a single-line shell script.
Executing something like this...
i=2; while [ $i -le 10 ]; do if [ $i -ne 3 -a $i -ne 5 ] echo $i " not equal to 3 or 5"; else echo $i; i=`expr $i + 1`; done
...I get the error
bash: syntax error near unexpected token `else'
On another hand if I remove the semicolon from between ...3 or 5"
and else echo...
, and try something like this...
i=2; while [ $i -le 10 ]; do if [ $i -ne 3 -a $i -ne 5 ] echo $i " not equal to 3 or 5" else echo $i; i=`expr $i + 1`; done
...then I get the error:
syntax error near unexpected token `done'
This is on an Ubuntu 14.04, in case it matters.
Am I perhaps missing some kind of a parenthesis somewhere, or is it something else?
Solution 1:[1]
This should work:
i=2; while [ $i -le 10 ]; do if [ $i -ne 3 -a $i -ne 5 ]; then echo $i " not equal to 3 or 5"; else echo $i; fi; i=`expr $i + 1`; done
and this should also work:
i=2; while [ $i -le 10 ]; do [ $i -ne 3 -a $i -ne 5 ] && echo "$i not equal to 3 or 5" || echo $i; i=$((i+1)); done
But I am not sure if it makes sense to write this in only one line
Solution 2:[2]
You still need a then
, and a fi
, and enough semicolons.
i=2; while [ $i -le 10 ]; do if [ $i -ne 3 -a $i -ne 5 ]; then echo "$i not equal to 3 or 5"; else echo $i; fi; i=$(expr $i + 1); done
The replacement of back-quotes `…`
with $(…)
is just a general good idea, not crucial to this discussion.
If written out conventionally on multiple lines (without semicolons), you'd have:
i=2
while [ $i -le 10 ]
do
if [ $i -ne 3 -a $i -ne 5 ]
then echo "$i not equal to 3 or 5"
else echo $i
fi
i=$(expr $i + 1)
done
To convert that to a single line, you need a semicolon after each statement and condition:
i=2;
while [ $i -le 10 ];
do
if [ $i -ne 3 -a $i -ne 5 ];
then echo "$i not equal to 3 or 5";
else echo $i;
fi;
i=$(expr $i + 1);
done
And now the white space (including newlines) can be replaced by single spaces on a single line.
And you could use i=$(($i + 1))
or even (in Bash) ((i++))
in place of expr
, which avoids the use of the external command expr
; the shell does the arithmetic internally.
I don't think there is a good reason to flatten the script onto one line.
Solution 3:[3]
Each if
needs a then
and fi
:
i=2; while [ $i -le 10 ]; do if [ $i -ne 3 -a $i -ne 5 ] ; then echo $i " not equal to 3 or 5" ; else echo $i; i=`expr $i + 1`; fi ; done
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jonathan Leffler |
Solution 2 | |
Solution 3 | choroba |