16

I've never programed in bash... yet I'm trying to solve a problem for an anchievement in a game (codingame.com)

I have the following code:

for (( i=0; i<N-1; i++ )); do tmp=$(( sorted_array[i+1] - sorted_array[i] )); if [ $tmp < $result ]; then result=$tmp fi done 

And this error:

/tmp/Answer.sh: line 42: syntax error near unexpected token `done'at Answer.sh. on line 42 /tmp/Answer.sh: line 42: `done' at Answer.sh. on line 42 

I want to compare adjacent values of my array and store the minimun diference between them... but I cant figure how to do an If statement in bash

2
  • 1
    Running this through shellcheck.net would catch some items which, for that matter, folks here haven't. Commented Jun 29, 2015 at 18:43
  • 2
    Mind you -- if (( tmp < result )); then result=$tmp; fi is also an option, which gets rid of the -lt vs < issue, and the potential for quoting. Commented Jun 29, 2015 at 18:46

3 Answers 3

22

Each command must be properly terminated, either by a newline or a semi-colon. In this case, you need to separate the assignment of result from the keyword fi. Try adding a semi-colon;

for (( i=0; i<N-1; i++ )); do tmp=$(( sorted_array[i+1] - sorted_array[i] )) if [ "$tmp" -lt "$result" ]; then result=$tmp; fi done 

Also, you need to use lt rather than <, since < is a redirection operator. (Unless you intend to run a command named $tmp with input from a file named by the variable $result)

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

12 Comments

The commands needs to be separated by semi-colons, not terminated by them.
separating the tokens serves to terminate the command in the parser.
The semicolon indicates the end of a statement, it doesn't terminate anything.
Fine, it terminates a statement then, are you arguing with yourself now ??
@ikegami Stop to be a pedantic fool here! Fix your own answer since it is actually wrong.
|
11

You are missing a semicolon and need to use -lt instead of <, as others pointed out.

An alternative to the if statement would be to use the logical and operator &&:

for (( i=0; i<N-1; i++ )); do tmp=$(( sorted_array[i+1] - sorted_array[i] )) [ $tmp -lt $result ] && result=$tmp done 

4 Comments

@User112638726 You think if somebody ask "How do I jump out of the window" I'm not allowed to answer "Please don't do it!"? Is does explicitely say: Read the question carefully. What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative.. Please read the FAQ before you down-vote and/or comment posts.
@User112638726 Link to the FAQ: stackoverflow.com/help/how-to-answer .. You actually did vandalizm, I've flagged that.
Poor analogy, they're not doing anything dangerous. You've just posted an identical answer to the accepted one with a a pointless addition of &&, which does nothing but hurt readability.
So you think a test && cmd is not a viable alternative for a single command, one-line if statement in bash? Common! Discussion ended.
-1

Your if needs to be followed by a fi command, but you don't have any such command. You have a fi in your code, but it's in the middle of another command, so it no more completes the if then the fi in echo fi would. If you're going to merge lines together, you need to use a semi-colon to separate the commands.

So to collapse

for (( i=0; i<N-1; i++ )) do tmp=$(( sorted_array[i+1] - sorted_array[i] )) if [ $tmp -lt $result ] then result=$tmp fi done 

you'd use

for (( i=0; i<N-1; i++ )); do tmp=$(( sorted_array[i+1] - sorted_array[i] )) if [ $tmp -lt $result ]; then result=$tmp; fi done 
  • Exception: do and then can be followed by a command, so you don't need a semi-colon after them when you merge in the next line.

  • Notice how you don't need to terminate your commands with ;? ; is only needed between commands.

  • Inside of a test ([]), -lt is used to compare numbers.

1 Comment

You may want to use the arithmetic operator for the comparison -lt

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.