#!/bin/sh
re="\/$"
if [ $1 =~ $re ]; then
echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
exit 1
fi
実行./file.sh hello/
結果は[: 29: hello: unexpected operator
シェルスクリプトでは、この正規表現のアプローチは間違っているようです。
答え1
標準コマンドは演算子なしでtest
呼び出すこともできます。ほとんどのシェルにはこのコマンドが組み込まれています。[
=~
Kornシェルは、代替構文[[...]]
とは異なる構文解析規則を使用して構文(コマンドではない)を導入します。[[
zsh
bash
ある程度複製されますが、制限とは多くの違いがありますが、標準化されていないため、移植可能なスクリプトには使用しないでくださいsh
。
ksh93
拡張正規表現をワイルドカード対応に変換する方法は常にあります。
pattern=${ printf %P "regexp"; }
これにより、次のことができます。
[[ $var = $pattern ]]
後(2001 ksh93l~(E)regex
)また、正規表現を拡張正規表現と同様にglobに統合するので、次のことができます。
[[ $var = ~(E)regex ]]
このパターンマッチングはコマンドではなくコンストラクタ[[...]]
でのみ機能します。case
[
zsh
[
正規表現一致演算子がそのコマンドに追加され、[[...]]
2001年にモジュールで最初に使用されましたpcre
。構文はオリジナル[ string -pcre-match regex ]
またはです[[ string -pcre-match regex ]]
。
bash
=~
bash 3.0に演算子が追加されました。(2004年)。拡張正規表現を使用してください。 ksh93とzshはこれをまもなく追加しました(同じ違いがあります)。
ksh93
そしてbash-3.2
~上(該当するcompat31
オプションが有効になっていない場合)引用符を使用してください。脱出する正規表現演算子はあらゆる種類の混乱を引き起こします(ksh93ではバグが多かった)。これは[
、そのコマンドと同じ方法で使用できないことを意味します。zsh
そのような問題はありません(シェル引用には引用符が使用され、正規表現演算子では通常どおりバックスラッシュがエスケープされます)。したがって、演算子は=~
コマンドで動作します(記号のファイル名拡張演算子であるため、引用符が必要ですが)。zsh
[
=foo
zsh
yash
いいえ、[[...]]
しかし、その[
コマンドには=~
演算子(EREを使用)があり、期待どおりに動作します(例:zsh
's)。
(2023年編集)[[...]]
は2.49(2018)でyashのサポートを追加し、=~
引用の面ではbashに似ています。
いずれにせよ、[[...]]
POSIX演算子ではないため、=~
スクリプトに使用しないでください。sh
文字列の正規表現を一致させるための標準コマンドは次のとおりですexpr
。
if expr "x$var" : "x$regex" > /dev/null; then...
expr
正規表現は最初に固定されているため、演算子の値の問題を回避するにはこのトリックがx
必要です。拡張正規表現の代わりにデフォルトの正規表現を使用してください。$var
expr
expr
しかし、ほとんどの場合、単純なシェルパターンマッチングで十分であるため、正規表現は必要ありません。
case $var in
(pattern) echo matches
esac
答え2
#!/bin/sh
に変更し#!/bin/bash
、代わりに二重括弧を使用します。
if [[ $1 =~ $re ]]; then
これは(一般)テストコマンドとは反対の拡張テストコマンドです。バージョンでのみ利用=~
可能[[ ... ]]
で、Bash 3.0以降が必要です。
答え3
bash
以前のテストでは[
正規表現はサポートされていません。代わりに新しいテストを使用する必要があります[[
。
re="\/$"
if [[ $1 =~ $re ]]; then
echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}"
exit 1
fi
もっと見ることができます。ここ。
また、#!/bin/sh
shebang行を#!/bin/bash
。