Если вы пытаетесь написать переносимый код оболочки, ваши возможности для работы со строками ограничены. Вы можете использовать шаблоны сглаживания оболочки (которые намного менее выразительны, чем регулярные выражения) в конструкции case
:
export LC_COLLATE=C
read word
while
case "$word" in
*[!A-Za-z]*) echo >&2 "Invalid input, please enter letters only"; true;;
*) false;;
esac
do
read word
done
EDIT : установка LC_COLLATE
необходима, поскольку в большинстве не C
локалей диапазоны символов, такие как A-Z
, не имеют «очевидного» значения. Я предполагаю, что вы хотите только буквы ASCII; если вам также нужны буквы с диакритическими знаками, не меняйте LC_COLLATE
и заменяйте A-Za-z
на [:alpha:]
(поэтому весь шаблон становится *[![:alpha:]]*
).
Полные регулярные выражения см. В команде expr
. EDIT : обратите внимание, что expr
, как и некоторые другие базовые инструменты оболочки, имеет подводные камни с некоторыми специальными строками; z
символов ниже не позволяют интерпретировать $word
как зарезервированные слова expr
.
export LC_COLLATE=C
read word
while expr "z$word" : 'z[A-Za-z]*$' >/dev/null; then
echo >&2 "Invalid input, please enter letters only"
read word
fi
Если вы нацелены только на достаточно недавние версии bash, есть другие опции, такие как оператор =~
условных команд [[ ... ]]
.
Обратите внимание, что в вашей последней строке есть ошибка, первая команда должна быть
grep -i "$word" "$1"
Кавычки, потому что несколько нелогично, "$foo"
означает «значение переменной с именем foo
», тогда как обычный $foo
означает «принять значение foo
, разбить его на отдельные слова, где оно содержит пробел, и относитесь к каждому слову как к шаблону и пытайтесь расширить его ». (На самом деле, если вы уже проверили, что $word
содержит только буквы, оставление кавычек не принесет никакого вреда, но требуется больше времени, чтобы подумать об этих особых случаях, чем просто ставить кавычки каждый раз.)