Поиск по нескольким каталогам

Вы могли бы использовать оператор caseв тесте if, но код выглядел бы немного неуклюжим:

if case "$1" in (cat|dog|mouse) true ;; (*) false; esac; then
    printf '"%s" is one of cat, dog or mouse\n' "$1"
else
    printf '"%s" is unknown\n' "$1"
fi

или чуть короче,

if ! case "$1" in (cat|dog|mouse) false; esac; then
    printf '"%s" is one of cat, dog or mouse\n' "$1"
else
    printf '"%s" is unknown\n' "$1"
fi

Предложение caseиспользуется только для сопоставления с образцом для предложения if. Он вводит ненужный тест на истинность/ложь.

Лучше просто использоватьcase:

case "$1" in
    cat|dog|mouse)
        printf '"%s" is one of cat, dog or mouse\n' "$1"
        ;;
    *)
        printf '"%s" is unknown\n' "$1"
esac

Не делай этого:

is_one_of () {
    eval "case $1 in ($2) return 0; esac"
    return 1
}

if is_one_of "$1" 'cat|dog|mouse'; then
    printf '"%s" is one of cat, dog or mouse\n' "$1"
else
    printf '"%s" is unknown\n' "$1"
fi

или это:

is_one_of () (
    word=$1
    shift
    IFS='|'
    eval "case $word in ($*) return 0; esac"
    return 1
)

if is_one_of "$1" cat dog mouse; then
    printf '"%s" is one of cat, dog or mouse\n' "$1"
else
    printf '"%s" is unknown\n' "$1"
fi

... потому что вы просто добавляете еще больше опасного хлама, просто чтобы иметь возможность использовать оператор ifв своем коде вместо вполне разумного оператора case.

0
28.04.2020, 13:37
2 ответа

Это не имеет отношения к grep, а к вашей текущей оболочке. Оболочка расширяет *.cppдо всех имен файлов cpp в вашем текущем каталоге перед запуском команды grep. Поскольку он не может найти ни одного имени файла, glob *.cppостается незаполненным оболочкой. Команда grepпытается увидеть, что это файл, но выдает, что это не настоящий файл.

У вас есть несколько вариантов, используйтеfind

find. -type f -name "*.cpp" -exec grep -r zlib {} +

или, если вы используете оболочку bash, установите параметр nullglob, чтобы перестать возвращать un -расширенный глобус как допустимый результат. (..)— сделать параметр расширенной оболочки временным, а не постоянным в оболочке. Причина наличия опции --include=*.cppзаключается в том, что с установленной опцией, если расширение глобуса не удается, *.cppстановится пустым, а ваша команда становится grep -r zlib, что означает поиск во всем подкаталоге -ниже.

( shopt -s nullglob; grep -r --include=*.cpp zlib. ; )

Другой вариант, который не включает опцию --includeдля grep, но использует globstar, который позволяет рекурсивное расширение универсальных объектов в подкаталогах -

( shopt -s nullglob globstar; grep -rH zlib **/*.cpp  ; )

Помните, что --include=и -Hявляются параметрами grep GNU и несовместимы с POSIX.

3
19.03.2021, 02:21

Пользователи оболочки zsh сразу же заметят, что у них есть встроенный синтаксис подстановки, который позволяет это сделать естественным образом, используя двойную звездочку:

grep -r zlib **/*.cpp

Вы можете запустить 'zsh' только один раз, если хотите, просто запустив 'zsh', вам не нужно переключаться на него постоянно.

0
19.03.2021, 02:21

Теги

Похожие вопросы