One line if statement in bash

33,419

Solution 1

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)

Solution 2

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
Share:
33,419
RagnaRock
Author by

RagnaRock

Programer in C#.net Also taking baby steps in web development

Updated on July 16, 2020

Comments

  • RagnaRock
    RagnaRock almost 4 years

    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

  • ikegami
    ikegami almost 9 years
    The commands needs to be separated by semi-colons, not terminated by them.
  • William Pursell
    William Pursell almost 9 years
    separating the tokens serves to terminate the command in the parser.
  • 123
    123 almost 9 years
    The semicolon indicates the end of a statement, it doesn't terminate anything.
  • 123
    123 almost 9 years
    You may want to use the arithmetic operator for the comparison -lt
  • 123
    123 almost 9 years
    Fine, it terminates a statement then, are you arguing with yourself now ??
  • hek2mgl
    hek2mgl almost 9 years
    @ikegami Stop to be a pedantic fool here! Fix your own answer since it is actually wrong.
  • William Pursell
    William Pursell almost 9 years
    "separating" is probably clearer, and "separating the tokens" makes perfect sense, but is not quite accurate. The $tmp token is already separated from the fi token.
  • 123
    123 almost 9 years
    You just said it doesn't need to be terminated by the semi colons, then corrected me saying it does ? MAke up your mind.
  • William Pursell
    William Pursell almost 9 years
    But, no, "separating the commands" makes no sense, because fi is not a command but a keyword. The problem is that without the semi-colon, the command shell is parsing the command as the sequence result=$tmp fi, so it tries to run a command fi with result set in its environment, because the assignment operator as a stand alone command was not properly terminated with a semi-colon.
  • ikegami
    ikegami almost 9 years
    Still says you need to terminate the commands, but it's not true. You can remove the ; from the OP's second line
  • ikegami
    ikegami almost 9 years
    @User112638726, Fixed.
  • William Pursell
    William Pursell almost 9 years
    @ikegami Yes, you can omit the semi-colon, but the command is still terminated by the newline. I agree with you that 'terminate the commands' is potentially misleading, but it is correct.
  • Charles Duffy
    Charles Duffy almost 9 years
    Needs more quotes. If result is empty (or has a non-numeric value) on the first pass, it can split into a number of words other than one. And if IFS contains digits, even worse...
  • hek2mgl
    hek2mgl almost 9 years
    @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.
  • hek2mgl
    hek2mgl almost 9 years
    @User112638726 Link to the FAQ: stackoverflow.com/help/how-to-answer .. You actually did vandalizm, I've flagged that.
  • 123
    123 almost 9 years
    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.
  • hek2mgl
    hek2mgl almost 9 years
    So you think a test && cmd is not a viable alternative for a single command, one-line if statement in bash? Common! Discussion ended.
  • Timo
    Timo almost 2 years
    After then no semicolon, otherwise you get error.