ANDed условное использование regexp и переменных

Я хочу проверить, имеет ли строка, считанная из файла, определенное начало И конец, содержащий слово, содержащееся в переменной. Вот какой код:

Входной файл:

line one #; line two #; line three blah line four 

Минимальный сценарий, который терпит неудачу:

 declare ENDOFLINE= "blah" exec 3< "inputfile" while read LINE <&3 do if [[ ("$LINE" =~ "^#;") && (( ("$LINE" =~ "${ENDOFLINE%$}") )) ]]; then echo score! else echo no score fi done 

Но если я это сделаю:

 if [[ ("$LINE" =~ "^#;") && (( ("$LINE" =~ "blah$") )) ]]; 

ему удаётся определить правильную строку (=> #; строка три бла). Другими словами, мне нужно сложное тестовое условие, когда первый тест заключается в том, является ли начало строки «#;» а конец строки – строка, содержащаяся в переменной $ ENDOFLINE.

Спасибо за любую помощь.

  • Как добавить статус батареи в zsh в крайнем правом положении?
  • Есть ли LC_COLLATE, который сортирует точку перед тире?
  • смотреть случайно упорядоченные видео в одном экземпляре mpv
  • При использовании zsh tab-completion игнорируйте CDPATH, если локальный файл или каталог совпадают
  • Byobu - Новое окно с той же сессией ssh?
  • Возможная ошибка перенаправления в zsh 5x
  • Как повторно использовать шаблон файла в .gitignore в bash / zsh?
  • Таинственное повторение введенной команды в оболочке
  • 2 Solutions collect form web for “ANDed условное использование regexp и переменных”

    Похож на простую ошибку: ${ENDOFLINE%$} $ в конце $ENDOFLINE , но то, что вы хотите сделать, это использовать $ENDOFLINE буквально и иметь $ после него, чтобы указать конец строки.

     if [[ ("$LINE" =~ "^#;") && (( ("$LINE" =~ "${ENDOFLINE}$") )) ]]; 

    Это работает в zsh, но не в ksh или bash. Bash требует, чтобы regexp $ был некорректным (в противном случае это интерпретируется буквально), а ksh не любит двойные скобки внутри [[ … ]] (он интерпретирует их как арифметическую инструкцию). Эта более простая строка работает во всех трех оболочках (обратите внимание, что [[…]] – одно из немногих мест, где вам не нужно "…" вокруг переменных расширений):

     if [[ $LINE =~ ^"#;" && $LINE =~ $ENDOFLINE$ ]]; 

    Если $ENDOFLINE никогда не перекрывается с #; (например, если ENDOFLINE : ;foo , вы будете принимать #;;foo но отклоняете #;foo ), вы можете уменьшить это до одного теста:

     if [[ $LINE =~ ^"#;".*$ENDOFLINE$ ]]; 

    Вы также можете использовать шаблон шаблона вместо regexp:

     if [[ $LINE = "#;"*"$ENDOFLINE" ]]; 

    Конструкция [[…]] не существует во всех оболочках, она специфична для bash, ksh и zsh. На других оболочках (Bourne, dash, anything POSIX) вы можете выполнять подстановочные соответствия с конструкцией case :

     case $LINE in "#;"*"$ENDOFLINE") echo score;; *) echo no score;; esac 

    Вы также можете сделать это, используя grep:

     end=blah while read line; do if grep -Eq "^#;.*$end$" <<< "$line"; then echo score! else echo no score fi done 

    (Это в bash, синтаксис может немного отличаться в других оболочках, но принцип тот же.)

    Linux и Unix - лучшая ОС в мире.