[bash] Syntax error near unexpected token 'fi'

I'm trying to write a script that removes all the .jpg's that end in an odd number. This is my code:

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if[$((fname %  2)) -eq 1 ] then
    echo "removing $fname\n"
    rm $f
  fi
done

When I run it it outputs start and then says "syntax error near unexpected token 'fi'"

When I had then on the line after if it said "syntax error near unexpected token 'then'"

How do i fix this?

This question is related to bash

The answer is


The first problem with your script is that you have to put a space after the [.
Type type [ to see what is really happening. It should tell you that [ is an alias to test command, so [ ] in bash is not some special syntax for conditionals, it is just a command on its own. What you should prefer in bash is [[ ]]. This common pitfall is greatly explained here and here.

Another problem is that you didn't quote "$f" which might become a problem later. This is explained here

You can use arithmetic expressions in if, so you don't have to use [ ] or [[ ]] at all in some cases. More info here

Also there's no need to use \n in every echo, because echo places newlines by default. If you want TWO newlines to appear, then use echo -e 'start\n' or echo $'start\n' . This $'' syntax is explained here

To make it completely perfect you should place -- before arbitrary filenames, otherwise rm might treat it as a parameter if the file name starts with dashes. This is explained here.

So here's your script:

#!/bin/bash
echo "start"
for f in *.jpg
do
    fname="${f##*/}"
    echo "fname is $fname"
    if (( fname % 2 == 1 )); then
        echo "removing $fname"
        rm -- "$f"
    fi
done

Use Notepad ++ and use the option to Convert the file to UNIX format. That should solve this problem.


"Then" is a command in bash, thus it needs a ";" or a newline before it.

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [$[fname%2] -eq 1 ]
  then
    echo "removing $fname\n"
    rm $f
  fi
done