2011-01-14 98 views
0

我想知道如何在bash腳本中創建動態case語句。bash中的動態case語句

例如,假設我有一個awk語句,其內容如下

red 
green 
blue 

在這種情況下的輸出,輸出可隨時更改。

我試圖然後執行不同的邏輯,如果一個值包含在這個awk輸出。

因此,如果上述數據是在$列表中,那麼我會在概念上喜歡做這樣的事情:

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

我試圖用它來建立一個動態的自定義選項卡完成功能(見http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2爲一些背景)。

任何想法?

謝謝。

+2

有趣的問題是:「你將如何指定每個動作的情況.....部分?」 – 2011-01-14 04:14:34

回答

3

A 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 
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 
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 
2

您可以在bash創建一個動態的case語句:

1)確保名單PIPE(|)分離。 IE瀏覽器。紅|綠|藍

2)包裝你的case語句在一個eval

例如:

valid="red|green|blue" 

eval "case \"$choice\" in 
    $valid) 
     echo do something good here 
     ;; 
    *) 
     echo invalid colour 
     ;; 
esac" 

這適用於簡單的變量處理,我不能保證,這將適用於所有情況。