2

bash スクリプトで動的な case ステートメントを作成する方法を理解しようとしています。

たとえば、次の内容の awk ステートメントの出力があるとします。

red
green
blue

このシナリオでは、出力はいつでも変更できます。

この awk 出力に値が含まれている場合、別のロジックを実行しようとしています。

したがって、上記のデータが $list にある場合、概念的には次のようにしたいと思います。

case "${my_var}" in
    $list)
        .....
    something_else)
        .....
esac

これを使用して、動的なカスタム タブ補完機能を構築しようとしています (背景についてはhttp://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2を参照してください)。

何か案は?

ありがとう。

4

6 に答える 6

2

これを case ステートメントで行うことはできませんが、独自のヘルパーをセットアップしてリストのメンバーシップをチェックするのは簡単です。

# stub to simulate this arbitrary call
my_awk_command() { printf '%s\n' red green blue; }
# helper to check list membership
list_contains() {
  local tgt="$1"; shift
  while (( $# )); do
    if [[ $1 = "$tgt" ]] ; then
      return 0
    fi
    shift
  done
  return 1
}

# the below is Bash 4 functionality; see BashFAQ #1 on how to replace it
readarray -t awk_output < <(my_awk_command)

if list_contains "$my_var" "${my_awk_command[@]}"; then
  ...something...
elif [[ "$my_var" = something_else ]] ; then
  ...something else...
fi
于 2011-01-14T03:44:12.047 に答える
2

ステートメントは、おそらく仕事に適したcaseツールではありません。出力を配列に格納awkすると、配列をループして選択肢が含まれているかどうかを確認できます。また、おまけとして、それがどのインデックスであるかを把握することもできます。

#!/bin/bash

# Store command output in an array so each word is a separate array item.    
list=($(echo $'red\ngreen\nblue'))
my_var=blue

for ((i = 0; i < ${#list}; i++)); do
    if [[ ${list[$i]} = $my_var ]]; then
        echo "found at index $i"
        break
    fi
done

if ((i == ${#list})); then
    echo "not found"
fi
于 2011-01-14T03:49:19.253 に答える
1

これには、いくつかの異なるハッキーな方法でアプローチできます。

pattern=($(awk_command))     # red\ngreen\nblue\n
saveIFS=$IFS
IFS='|'
pattern="^(${pattern[*]})$"  # ^(red|green|blue)$  (perhaps hackish)
IFS=$saveIFS

# simple regex match if statement (not hackish)
if [[ $var =~ $pattern ]]
then
    do_something
fi

# or a backwards case statement (very hackish)
case 1 in    # this could be a variable or a command substitution
    $([[ $var =~ $pattern]] && echo 1) )  # the echo 1 could be another command or the 1 could be yet another variable
        do_something;;
    * )
        do_default;;
esac
于 2011-01-14T05:04:47.983 に答える