Есть ошибки и предупреждения. Также, пожалуйста, используйте shellcheck.net в подобных ситуациях.
Ошибки:
Пробел между while
и [
.
Пробел после [
и перед ]
.
Катастрофа, потому что нет done
, возможно, вы забыли или просто вставили половину своего кода.
Используйте [ a ] || [ b ]
вместо [ a || b ]
.
Предупреждения:
Вы должны использовать read -r
вместо read
.
Имена переменных в двойных кавычках, иначе это не будет работать, если они содержат специальные символы.
Правильный код:
while true
do
echo "Enter the number"
read -r Num
while [ "$Num" -lt 1 ] || [ "$Num" -gt 50 ]
do
echo "Please enter a new number "
read -r Num
done
done
Мы можем использовать функцию интерполяции тайм-кода соответствия -Perl (??{ match time regex })
, чтобы решить эту проблему. По сути, что он делает, основываясь на том, какая цитата соответствует, он помещает соответствующее действительное регулярное выражение для этой цитаты, так что механизм регулярных выражений поймает пару этой цитаты.
$ perl -lne '
print substr($&, 1, -2+length($&))
while
/(?:(["'\''])(??{q<(?:[^\\\\>.$1.q<]|\\\\.)*>.$1}))/gx;
' file
Результаты:
foo bar1
foo\"bar2
foo 'bar3
foo bar4
foo \'bar5
foo "bar6
Более гладкая запись вышеизложенного выглядит следующим образом:
$ perl -lne '
BEGIN {
$genRE = sub {
my $openingQ = shift;
# look in the Notes below for why
qq<(?:[^\\\\${openingQ}]|\\\\.)*>
};
}
print $2
while
/
(["'\'']) (?#: opening quote)
((??{ $genRE->($1) })) (?#: run of in between quote pair stuff)
\1 (?#: corresponding closing quote)
/gx;
' file
Примечания::
"........"
соответствует/"[^"]*"/
"...... \"......"
соответствует/"(?:[^\\"]|\\.)*"/
Другой perl
подход:
perl -lne 'print $2 while m{(["'\''])((?:\\.|(?!\1).)*+)\1}g'
Здесь используется отрицательный оператор опережающего просмотра в (?!\1).
для сопоставления символов, отличных от того, который соответствует первой группе захвата. Вы также можете просто покрыть случаи '...'
и "..."
отдельно с помощью:
perl -lne 'print $1 while m{(?|"((?:\\.|[^"])*+)"|'"'((?:\\\.|[^'])*+)')}g"