web-dev-qa-db-ja.com

bash正規表現のマッチ文字列

私は.tar.tar.bz2.tar.gzなどのファイルが与えられたときそれがファイルを解凍するために適切なスイッチでtarを使うように関数を含むbashスクリプトを書くことを試みています。

私はElifがファイル名をテストしてそれが何で終わっているのかを確かめるステートメントを使っていますが、正規表現のメタキャラクターを使って一致させることはできません。

私がコマンドラインで 'test'を使っているスクリプトを絶えず書き直す手間を省くために、以下のステートメントはうまくいくはずだと思いました。

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

私は問題が単純なものであることを確信していて、そして私は至る所で見ました、しかし、私はそれをどうやってやるのか分からない。誰かが私がこれを行うことができる方法を知っていますか?

132
user1587462

正規表現を一致させるには、=~演算子を使用する必要があります。

これを試して:

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

あるいは、==演算子と一緒にワイルドカード(正規表現の代わりに)を使用することができます。

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

移植性が問題にならない場合は、安全で強力なので[[testの代わりに[を使用することをお勧めします。詳しくは test [と[[? の違いは何ですか。

219
dogbane

これをする機能

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に応答して、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

(上記の正規表現はファイルの命名や拡張子に有効なものではありませんが、例としてはうまくいきます)

47
duality

ここにコメントするのに十分な担当者がいないので、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
8
user2066480

Bashを使っているので、これを行うために子プロセスを作成する必要はありません。これはbash内で完全に実行する1つの解決策です。

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

説明:シーケンス「コロンと1つ以上のスペース」の前後のグループは、パターン・マッチング演算子によってBASH_REMATCH配列に保管されます。

4
user1934428
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)

0
juan cortez

shopt -s nocasematch

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