Булевы выражения в сценариях оболочки

Какой "правильный" способ сделать следующее в виде логического выражения?

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

Ответ 1

В других решениях есть несколько распространенных ошибок: http://www.pixelbeat.org/programming/shell_script_mistakes.html

  • for i in $(ls ...) является избыточным/проблемным просто выполните: for i in $1/resources*; do ...

  • [ $i != file1 -a $1 != file2 ] У этого фактически есть 2 проблемы.

    а. $i не цитируется, поэтому имена с пробелами будут вызывать проблемы

    б. -a неэффективен, если stat файлы, так как он не является короткозамкнутым (я знаю, что это не stat ing файлы).

Итак, попробуйте:

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

Ответ 2

Еще короче:

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;

-a в выражении if является эквивалентом логического И в shell-тестах. Подробнее см. man test

Ответ 3

Рассмотрим использование оператора case:

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

Ответ 4

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

Ответ 5

Для справок в будущем рекомендуется использовать [[test operator. Принятый ответ близок, и все упомянутое относится, но для этого ответа потребуется много котировок и звонков на несколько тестов.

Предпочтительным способом будет что-то вроде:

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