3

I have a section of code in a bash shell script that looks like this, with a series of consecutive conditionals:

#do January first, no matter what
awk '$4 == "Jan" {print $0}' < last-output.txt | sort -u -k1 > Jan.txt
awk -F'[ +:()]+' 'FNR==NR{a[$1]; next;} !($1 in a){next} NF==13{b[$1]+=$12/60+$11} NF==14{b[$1]+=$13/60+$12+24*$11} END{print "[Jan]"; for (n in b)print n,b[n],"hours"; print "\n"}' namelist Jan.txt > t1.txt
(IFS="|"; grep -vE "(${name_to_exclude[*]})" t1.txt > t1_new.txt)

#now iterate month by month for the rest of the months, up to the current month
if [ ${this_month} -ge 2]
        awk '$4 == "Feb" {print $0}' < last-output.txt | sort -u -k1 > Feb.txt
        awk -F'[ +:()]+' 'FNR==NR{a[$1]; next;} !($1 in a){next} NF==13{b[$1]+=$12/60+$11} NF==14{b[$1]+=$13/60+$12+24*$11} END{print "[Feb]"; for (n in b)print n,b[n],"hours"; print "\n"}' namelist Feb.txt > t2.txt
        (IFS="|"; grep -vE "(${name_to_exclude[*]})" t2.txt > t2_new.txt)
fi
if [ ${this_month} -ge 3]
        awk '$4 == "Mar" {print $0}' < last-output.txt | sort -u -k1 > Mar.txt
        awk -F'[ +:()]+' 'FNR==NR{a[$1]; next;} !($1 in a){next} NF==13{b[$1]+=$12/60+$11} NF==14{b[$1]+=$13/60+$12+24*$11} END{print "[Mar]"; for (n in b)print n,b[n],"hours"; print "\n"}' namelist Mar.txt > t3.txt
        (IFS="|"; grep -vE "(${name_to_exclude[*]})" t3.txt > t3_new.txt)
fi

continuing through all the months all the way to December.

When I try to run the script I get this error message:

./login-act.sh: line 37: syntax error near unexpected token `fi'
./login-act.sh: line 37: `fi'

(line 37 is the first occurrence of "fi")

How do I make this error go away?

Connor
  • 43
  • 1
  • 3
  • 2
    make sure theres a space each side of the statement in the square brackets? – mattbawn Jul 17 '17 at 20:10
  • And that's because `[` is not just syntax, it's actually a [command](https://www.gnu.org/software/bash/manual/bashref.html#index-test) that requires its final argument to be `]`: arguments in bash are separated by whitespace. – glenn jackman Jul 17 '17 at 20:33
  • [shellcheck](http://shellcheck.net) autodetects common syntax issues like this – that other guy Jul 17 '17 at 21:56
  • For your consideration: nobody ever seems to ask why `test$x -ge 2` produces an error. Join my boycott of `[` :) – chepner Sep 10 '17 at 15:27

2 Answers2

3

Add then after if condition and add space before ]:

if [ ${this_month} -ge 2 ]; then
        awk '$4 == "Feb" {print $0}' < last-output.txt | sort -u -k1 > Feb.txt
        awk -F'[ +:()]+' 'FNR==NR{a[$1]; next;} !($1 in a){next} NF==13{b[$1]+=$12/60+$11} NF==14{b[$1]+=$13/60+$12+24*$11} END{print "[Feb]"; for (n in b)print n,b[n],"hours"; print "\n"}' namelist Feb.txt > t2.txt
        (IFS="|"; grep -vE "(${name_to_exclude[*]})" t2.txt > t2_new.txt)
fi

You can find more information in the Bash manual on Bash conditional expressions and the [ builtin command and the [[ compound commmand.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Vadim Beskrovnov
  • 941
  • 6
  • 18
1

@Vadim has the right answer. Note that there can be many commands between if and then -- this is valid bash

if
    echo hello world
    ls
    make
    # etc etc etc
    true
    date
    false
then
    echo success
else
    echo not success
fi

Referring to the bash manual:

The syntax of the if command is:

if test-commands; then
  consequent-commands;
[elif more-test-commands; then
  more-consequents;]
[else alternate-consequents;]
fi

The test-commands list is executed, and if its return status is zero, the consequent-commands list is executed. If test-commands returns a non-zero status, each elif list is executed in turn, and if its exit status is zero, the corresponding more-consequents is executed and the command completes. If ‘else alternate-consequents’ is present, and the final command in the final if or elif clause has a non-zero exit status, then alternate-consequents is executed. The return status is the exit status of the last command executed, or zero if no condition tested true.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352