11

What's the "right" way to do the following as a boolean expression?

for i in `ls $1/resources`; do
    if [ $i != "database.db" ]
    then
        if [ $i != "tiles" ]
        then
            if [ $i != "map.pdf" ]
            then
                if [ $i != "map.png" ]
                then
                    svn export -q $1/resources/$i ../MyProject/Resources/$i
...

5 Answers 5

11

The other solutions have a couple of common mistakes: http://www.pixelbeat.org/programming/shell_script_mistakes.html

  1. for i in $(ls ...) is redundant/problematic just do: for i in $1/resources*; do ...

  2. [ $i != file1 -a $1 != file2 ] This actually has 2 problems.

    a. The $i is not quoted, hence names with spaces will cause issues

    b. -a is inefficient if stating files as it doesn't short circuit (I know the above is not stating files).

So instead try:

for i in $1/resources/*; do
    if [ "$i" != "database.db" ] &&
       [ "$i" != "tiles" ] &&
       [ "$i" != "map.pdf" ] &&
       [ "$i" != "map.png" ]; then
        svn export -q "$i" "../MyProject/Resources/$(basename $i)"
    fi
done
0
7

Even shorter:

for i in `ls $1/resources`; do
  if [ $i != databse.db -a $i != titles -a $i != map.pdf ]; then
    svn export -q $1/resources/$i ../MyProject/Resources/$i
  fi
done;

The -a in the if expression is the equivalent of the boolean AND in shell-tests. For more see man test

0
3

Consider using a case statement:

for i in $(ls $1/resources); do
    case $i in
        database.db|tiles|map.pdf|map.png)
           ;;
        *)
           svn export -q $1/resources/$i ../MyProject/Resources/$i;;
    esac
done
1
for i in `ls $1/resources`; do
    if [ $i != "database.db" ] && [ $i != "tiles" ] && [ $i != "map.pdf" ] && [ $i != "map.png" ]; then
        svn export -q $1/resources/$i ../MyProject/Resources/$i
1

For future reference, the new [[ test operator is preferred. The accepted answer is close and everything mentioned applies, but that answer will require lots of quoting and calls to multiple tests.

The preferred method would be something like:

for i in $1/resources/*; do
    if [[ $i != "database.db" && $i != "tiles" &&
                $i != "map.pdf" && $i != "map.png" ]]; then
        svn export -q "$i" "../MyProject/Resources/$(basename $i)"
    fi
done

Not the answer you're looking for? Browse other questions tagged or ask your own question.