Question

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
...
Was it helpful?

Solution

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

OTHER TIPS

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

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
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

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top