GNU/Linux >> Linux の 問題 >  >> Linux

ケース条件として変数を使用する方法は?

|で区切られたさまざまな文字列で構成される変数を使用しようとしています caseとして ステートメントテスト。例:

string=""foo"|"bar""
read choice
case $choice in
    $string)
        echo "You chose $choice";;
    *)
        echo "Bad choice!";;
esac

fooと入力できるようにしたい またはbar caseの最初の部分を実行します 声明。ただし、両方のfoo およびbar 2番目に連れて行ってください:

$ foo.sh
foo
Bad choice!
$ foo.sh
bar
Bad choice!

"$string"を使用する $stringの代わりに 違いはありません。 string="foo|bar"も使用しません 。

私はこの方法でそれができることを知っています:

case $choice in
    "foo"|"bar")
        echo "You chose $choice";;
    *)
        echo "Bad choice!";;
esac

さまざまな回避策を考えることができますが、変数をcaseとして使用できるかどうかを知りたいです。 bashの状態。それは可能ですか?もしそうなら、どのように?

承認された回答:

バッシュマニュアルには次のように記載されています:

[[(]パターン[|パターン]…)リストの大文字小文字の区別;; ]…esac

調べた各パターンは、チルダ展開、パラメーターと変数の展開、算術置換、コマンド置換、およびプロセス置換を使用して展開されます。

いいえ«パス名拡張»

したがって、パターンは«パス名展開»では展開されません。

したがって、パターンに「|」を含めることはできません中身。のみ:2つのパターンを「|」で結合できます。

これは機能します:

s1="foo"; s2="bar"    # or even s1="*foo*"; s2="*bar*"

read choice
case $choice in
    $s1|$s2 )     echo "Two val choice $choice"; ;;  # not "$s1"|"$s2"
    * )           echo "A Bad  choice! $choice"; ;;
esac

«ExtendedGlobbing»の使用

ただし、word patternと一致します «パス名拡張»ルールを使用します。
および«拡張グロビング»ここ、ここ、およびここでは、交互の( "|")パターンを使用できます。

これも機能します:

shopt -s extglob

string='@(foo|bar)'

read choice
    case $choice in
        $string )      printf 'String  choice %-20s' "$choice"; ;;&
        $s1|$s2 )      printf 'Two val choice %-20s' "$choice"; ;;
        *)             printf 'A Bad  choice! %-20s' "$choice"; ;;
    esac
echo

文字列コンテンツ

次のテストスクリプトは、fooのいずれかを含むすべての行に一致するパターンを示しています。 またはbar どこでも'*$(foo|bar)*' または2つの変数$s1=*foo* および$s2=*bar*

テストスクリプト:

shopt -s extglob    # comment out this line to test unset extglob.
shopt -p extglob

s1="*foo*"; s2="*bar*"

string="*foo*"
string="*foo*|*bar*"
string='@(*foo*|*bar)'
string='*@(foo|bar)*'
printf "%sn" "$string"

while IFS= read -r choice; do
    case $choice in
        "$s1"|"$s2" )   printf 'A first choice %-20s' "$choice"; ;;&
        $string )   printf 'String  choice %-20s' "$choice"; ;;&
        $s1|$s2 )   printf 'Two val choice %-20s' "$choice"; ;;
        *)      printf 'A Bad  choice! %-20s' "$choice"; ;;
    esac
    echo
done <<-_several_strings_
f
b
foo
bar
*foo*
*foo*|*bar*
"foo"
"foo"
afooline
onebarvalue
now foo with spaces
_several_strings_

Linux
  1. LinuxでBusyBoxを使用する方法

  2. Nginxを使用してリダイレクトする方法

  3. 間接変数評価を行う方法は?

  1. Bash履歴コマンドの使用方法

  2. Linuxでcronを使用する方法

  3. vimでpylintを使用する方法

  1. LinuxでFINDを使用する方法

  2. LinuxでSuコマンドを使用する方法

  3. dos2unix の使い方