我试图写一个bash脚本,其中包含一个函数,所以当给.tar, .tar。Bz2, .tar.gz等文件,它使用tar和相关开关来解压文件。

我使用if elif然后语句测试文件名,看看它以什么结尾,我不能让它匹配使用正则表达式元字符。

为了节省不断重写脚本,我在命令行使用“test”,我认为下面的语句应该工作,我已经尝试了括号,引号和元字符的每一个组合,但它仍然失败。

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

我相信这个问题很简单,我到处都找过了,但我不知道该怎么做。有人知道我该怎么做吗?


当前回答

由于您使用的是bash,因此不需要为此创建子进程。下面是一个完全在bash中执行的解决方案:

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

解释:序列“冒号和一个或多个空格”前后的组由模式匹配操作符存储在BASH_REMATCH数组中。

其他回答

我没有足够的代表来评论这里,所以我提交了一个新的答案,以改善dogbane的答案。点。在regexp中

[[sed-4.2.2.tar。Bz2 =~ tar。Bz2 $]] && echo匹配

将匹配任何字符,而不仅仅是'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[1]}:${BASH_REMATCH[2]}

解释:序列“冒号和一个或多个空格”前后的组由模式匹配操作符存储在BASH_REMATCH数组中。

一个函数来做这个

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
}

其他的注意

为了回应上面评论中的Aquarius Power,我们需要将正则表达式存储在一个var上

变量BASH_REMATCH在匹配表达式后被设置,${BASH_REMATCH[n]}将匹配下面${BASH_REMATCH[1]} = "compressed"和${BASH_REMATCH[2]} = ".gz"中括号括起来的第n组ie

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

(上面的正则表达式并不是一个有效的文件命名和扩展名,但它适用于这个例子)

要匹配正则表达式,您需要使用=~操作符。

试试这个:

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

或者,你可以使用通配符(而不是正则表达式)和==操作符:

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

如果可移植性不是问题,我建议使用[[而不是[或test,因为它更安全、更强大。参见test,[和[[的区别是什么?获取详细信息。