Вы могли бы использовать оператор 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
.
Это не имеет отношения к 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.
Пользователи оболочки zsh сразу же заметят, что у них есть встроенный синтаксис подстановки, который позволяет это сделать естественным образом, используя двойную звездочку:
grep -r zlib **/*.cpp
Вы можете запустить 'zsh' только один раз, если хотите, просто запустив 'zsh', вам не нужно переключаться на него постоянно.