Строка Grep в двойных и одинарных кавычках

Есть ошибки и предупреждения. Также, пожалуйста, используйте shellcheck.net в подобных ситуациях.

Ошибки:

  1. Пробел между whileи [.

  2. Пробел после [и перед ].

  3. Катастрофа, потому что нет done, возможно, вы забыли или просто вставили половину своего кода.

  4. Используйте [ a ] || [ b ]вместо [ a || b ].

Предупреждения:

  1. Вы должны использовать read -rвместо read.

  2. Имена переменных в двойных кавычках, иначе это не будет работать, если они содержат специальные символы.

Правильный код:

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

1
22.06.2020, 03:13
2 ответа

Мы можем использовать функцию интерполяции тайм-кода соответствия -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

Примечания::

  • "........"соответствует/"[^"]*"/
  • "...... \"......"соответствует/"(?:[^\\"]|\\.)*"/
  • аналогично и для одинарных кавычек.
4
18.03.2021, 23:25

Другой perlподход:

perl -lne 'print $2 while m{(["'\''])((?:\\.|(?!\1).)*+)\1}g'

Здесь используется отрицательный оператор опережающего просмотра в (?!\1).для сопоставления символов, отличных от того, который соответствует первой группе захвата. Вы также можете просто покрыть случаи '...'и "..."отдельно с помощью:

perl -lne 'print $1 while m{(?|"((?:\\.|[^"])*+)"|'"'((?:\\\.|[^'])*+)')}g"
3
18.03.2021, 23:25

Теги

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