4

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?

1
  • The basic idea is to simply use the end-of-line delimiter ';' wherever you would normally have a newline if you had written the script as a normally-formatted multi-line script. As noted below, you have missing then and fi's as well. Commented Dec 27, 2015 at 6:03

3 Answers 3

5

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

Sign up to request clarification or add additional context in comments.

1 Comment

You're right — it makes no sense to write it all one one line.
5

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.