How can I match a string with a regex in Bash?

后端 未结 6 1153
囚心锁ツ
囚心锁ツ 2020-12-02 05:04

I am trying to write a bash script that contains a function so when given a .tar, .tar.bz2, .tar.gz etc. file it uses tar with the rel

相关标签:
6条回答
  • 2020-12-02 05:09

    A Function To Do This

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

    Other Note

    In response to Aquarius Power in the comment above, We need to store the regex on a var

    The variable BASH_REMATCH is set after you match the expression, and ${BASH_REMATCH[n]} will match the nth group wrapped in parentheses ie in the following ${BASH_REMATCH[1]} = "compressed" and ${BASH_REMATCH[2]} = ".gz"

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

    (The regex above isn't meant to be a valid one for file naming and extensions, but it works for the example)

    0 讨论(0)
  • 2020-12-02 05:12

    Since you are using bash, you don't need to create a child process for doing this. Here is one solution which performs it entirely within bash:

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

    Explanation: The groups before and after the sequence "colon and one or more spaces" are stored by the pattern match operator in the BASH_REMATCH array.

    0 讨论(0)
  • 2020-12-02 05:15
    if [[ $STR == *pattern* ]]
    then
        echo "It is the string!"
    else
        echo "It's not him!"
    fi
    

    Works for me! GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

    0 讨论(0)
  • 2020-12-02 05:20

    I don't have enough rep to comment here, so I'm submitting a new answer to improve on dogbane's answer. The dot . in the regexp

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

    will actually match any character, not only the literal dot between 'tar.bz2', for example

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

    or anything that doesn't require escaping with '\'. The strict syntax should then be

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

    or you can go even stricter and also include the previous dot in the regex:

    [[ sed-4.2.2.tar.bz2 =~ \.tar\.bz2$ ]] && echo matched
    
    0 讨论(0)
  • 2020-12-02 05:33

    To match regexes you need to use the =~ operator.

    Try this:

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

    Alternatively, you can use wildcards (instead of regexes) with the == operator:

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

    If portability is not a concern, I recommend using [[ instead of [ or test as it is safer and more powerful. See What is the difference between test, [ and [[ ? for details.

    0 讨论(0)
  • 2020-12-02 05:35

    shopt -s nocasematch

    if [[ sed-4.2.2.$LINE =~ (yes|y)$ ]]
     then exit 0 
    fi
    
    0 讨论(0)
提交回复
热议问题