Вы можете поместить перенаправление в любую позицию простой команды (, т. е. вызвать псевдоним, функцию, встроенный или исполняемый файл с параметрами ). С другой стороны, если вы хотите применить перенаправление к составным командам, перенаправления должны появиться позже. Так устроен синтаксис оболочки. Например, следующие эквивалентны:
<myinput mycommand argument
mycommand <myinput argument
mycommand argument <myinput
, тогда как перенаправление не может быть перемещено в
while …; do …; done <myinput
{ command1; command2; } <myinput
Вы можете применить перенаправление к составной команде, только если она заканчивается ключевым словом или знаком препинания. Чтобы применить перенаправление к чему-то вроде foo && bar
, foo; bar
или foo | bar
, поместите команду в фигурные скобки, например.
{ foo && bar; } <myinput
Скрипты
while read a; do
echo "$a"
done <myfile
и
while read a <myfile; do
echo "$a"
done
оба синтаксически правильны, но второй не делает ничего полезного. Оператор перенаправления в команде означает:
<
). Таким образом, read a <myfile
снова открывает файл на каждой итерации, что означает, что он продолжает читать первую строку всегда.
Если вы хотите использовать цикл чтения while -и хотите сохранить окружающий стандартный ввод для тела цикла, читайте из другого файлового дескриптора.
while read a <&3; do
# commands that can use stdin
done 3<myfile
Оператор перенаправления <&3
просто дублирует дескриптор файла, он не «открывает файл снова» — в приведенном выше перечислении шаг 1 отсутствует.
Вы используете функции Perl-совместимых регулярных выражений (PCRE ). А именно, (?=...)
и (?:...)
не являются частью стандартных расширенных регулярных выражений, которые использует Bash.
Но мне кажется, что вы используете прежний (?=^.{4,253}$)
только для проверки длины строки. Если это верно, это легко заменить прямой проверкой длины строки:
if [ "${#domain}" -lt 4 ] || [ "${#domain}" -gt 253 ]; then
echo "Domain name is too short or too long"
fi
Тогда (?:...)
легко, это эквивалент (...)
, за исключением того, что он не захватывает. Дополнительные захваты не имеют значения в том, что соответствует регулярному выражению в целом, поэтому мы можем просто удалить ?:
из каждой открывающей скобки.
Также обратите внимание, что (по крайней мере в ERE )обратная косая черта в [a-zA-Z0-9\-]
соответствует буквальной обратной косой черте. Дефис можно сопоставить, просто поместив его в качестве первого или последнего символа в группу квадратных скобок (как в PCRE, так и в ERE ):[a-zA-Z0-9-]
.
С этими изменениями мы получаем:
^([a-zA-Z0-9](([a-zA-Z0-9-]){0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$
См. также:Почему мое регулярное выражение работает в X, но не в Y?