строка соответствия регулярного выражения bash



Я пытаюсь написать сценарий bash, который содержит функцию, поэтому при задании .tar,.tar.bz2,.tar.gz etc. файл он использует tar с соответствующими переключателями для распаковки файла.



Я использую операторы if elif then, которые проверяют имя файла, чтобы увидеть, чем он заканчивается, и я не могу заставить его соответствовать, используя метасимволы регулярных выражений.



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



test sed-4.2.2.tar.bz2 = tar.bz2$; echo $?
(this returns 1, false)


Я уверен, что проблема проста и я искала везде, но я не могу понять, как это сделать. Кто-нибудь знает как я могу это сделать?

666   6  

6 ответов:

чтобы соответствовать регулярным выражениям, вам нужно использовать =~ оператора.

попробуйте это:

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched

кроме того, вы можете использовать подстановочные знаки (вместо регулярных выражений) с == оператор:

[[ sed-4.2.2.tar.bz2 == *tar.bz2 ]] && echo matched

если переносимость не является проблемой, я рекомендую использовать [[ вместо [ или test как это безопаснее и мощнее. Смотрите в чем разница между тестом, [ и [[ ? для сведения.

Функция Для Этого

extract () {
  if [ -f  ] ; then
      case  in
          *.tar.bz2)   tar xvjf     ;;
          *.tar.gz)    tar xvzf     ;;
          *.bz2)       bunzip2      ;;
          *.rar)       rar x        ;;
          *.gz)        gunzip       ;;
          *.tar)       tar xvf      ;;
          *.tbz2)      tar xvjf     ;;
          *.tgz)       tar xvzf     ;;
          *.zip)       unzip        ;;
          *.Z)         uncompress   ;;
          *.7z)        7z x         ;;
          *)           echo "don't know ''..." ;;
      esac
  else
      echo "'' is not a valid file!"
  fi
}

Другое Примечание

в ответ на власть Водолея в комментарии выше,We need to store the regex on a var

переменная BASH_REMATCH устанавливается после того, как вы соответствуете выражению, и ${BASH_REMATCH[n]} будет соответствовать N-й группе, заключенной в скобки, т. е. в следующем ${BASH_REMATCH[1]} = "compressed" и ${BASH_REMATCH[2]} = ".gz"

if [[ "compressed.gz" =~ ^(.*)(\.[a-z]{1,5})$ ]]; 
then 
  echo ${BASH_REMATCH[2]} ; 
else 
  echo "Not proper format"; 
fi

(регулярное выражение выше не должно быть допустимым для именования файлов и расширений, но оно работает для примера)

у меня не хватает рэп комментировать здесь, поэтому я подаю новый ответ, чтобы улучшить ответ dogbane по. Точка. в регулярном выражении

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched

фактически будет соответствовать любому символу, а не только буквальной точке между 'tar.bz2', например

[[ sed-4.2.2.tar4bz2 =~ tar.bz2$ ]] && echo matched
[[ sed-4.2.2.tar§bz2 =~ tar.bz2$ ]] && echo matched

или все, что не требует побега с '\'. Строгий синтаксис должен быть

[[ sed-4.2.2.tar.bz2 =~ tar\.bz2$ ]] && echo matched

или вы можете пойти еще строже, а также предыдущих точкой в регулярное выражение:

[[ sed-4.2.2.tar.bz2 =~ \.tar\.bz2$ ]] && echo matched

shopt-s nocasematch

if [[ sed-4.2.2.$LINE =~ (yes|y)$ ]]
 then exit 0 
fi

Так как вы используете bash, вам не нужно создавать дочерний процесс для этого. Вот одно решение, которое выполняет его полностью в bash:

[[ $TEST =~ ^(.*):\ +(.*)$ ]] && TEST=${BASH_REMATCH[0]}:${BASH_REMATCH[1]}

пояснение: группы до и после последовательности "двоеточие и один или несколько пробелов" хранятся оператором соответствия шаблону в массиве BASH_REMATCH.

if [[ $STR == *pattern* ]]
then
    echo "It is the string!"
else
    echo "It's not him!"
fi

работает для меня! GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

Comments

    Ничего не найдено.