[解決済み】シェルのif文で複数の条件を表現するには?
質問
複数の条件をこのように表現したい。
if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]
then
echo abc;
else
echo efg;
fi
と表示されますが、スクリプトを実行すると
syntax error at line 15: `[' unexpected,
ここで、15行目がif ...を示すものです。
この条件では何が問題なのでしょうか?やはり
()
.
解決方法は?
古典的な手法(メタ文字のエスケープ)。
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
への参照を囲みました。
$g
二重引用符で囲むのは、一般的に良い習慣です。 厳密には、括弧は必要ありません。
-a
と
-o
を使うと、それらがなくても正しくなります。
なお
-a
と
-o
演算子は、POSIX仕様に含まれる
test
は、別名
[
の一部であったため)、主に後方互換性のためです。
test
は、例えば第7版UNIXのように)しかし、POSIXでは「時代遅れ」として明示的にマークされています。 Bash (
条件式
の古典的な意味とPOSIXの意味を先取りしているようです。
-a
と
-o
と、引数を取る独自の代替演算子で構成されています。
少し注意すれば、より現代的な
[[
演算子がありますが、BashとKorn Shell(例)のバージョンが同じである必要はないので注意してください。
for g in 1 2 3
do
for c in 123 456 789
do
if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
then echo "g = $g; c = $c; true"
else echo "g = $g; c = $c; false"
fi
done
done
Mac OS X の Bash 3.2.57 を使用した実行例です。
g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false
の変数を引用する必要はありません。
[[
と同じように
[
と同じように独立したコマンドではないためです。
[
があります。
古典的な質問ではありませんか?
私もそう思っていました。 しかし、別の選択肢もある、すなわち
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
確かに、「ポータブルシェル」のガイドラインを読むと
autoconf
ツールや関連パッケージでは、この表記法 - '
||
と'
&&
というのが彼らの推奨するところです。 というところまで行けると思います。
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
アクションがechoのような些細なものである場合、これは悪くないと思います。 繰り返されるアクションブロックが複数行に及ぶ場合は、繰り返しが苦痛になるので、以前のバージョンのいずれかが望ましいです - あるいは、アクションを関数にラップして、別の
then
ブロックを作成します。
関連
-
[解決済み] ConcatenationとAppendの違いについて【終了しました
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] シェルで、「2>&1」はどういう意味ですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] LinuxのシェルスクリプトでYes/No/Cancelの入力を促すにはどうしたらいいですか?
-
[解決済み] Bashシェルスクリプトの入力引数の存在確認
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Bashのif条件で「unary operator expected」エラーが発生する。
-
[解決済み】if [](角括弧)の「[: 引数が多すぎる」エラーの意味)
-
[解決済み] Bashで$()と`の違いはあるのでしょうか?重複] [重複
-
[解決済み] OS X で 'find' コマンドを使用して 'sed' を使用するとエラーが発生する。"無効なコマンドコードです。"
-
[解決済み] 値がベースに対して大きすぎる(エラートークンは "08")[重複]
-
[解決済み] curl: 引数リストが長すぎる
-
[解決済み] IPアドレスのまとめ方
-
[解決済み] MINGW64 "make build" エラー。"bash: make: コマンドが見つかりません"
-
[解決済み] Bashのif文で複数の条件を指定するとエラーが発生する
-
[解決済み] 二重括弧、片括弧、中括弧の使い方