2012-11-04 31 views
53

使用:最簡單的方法來檢查索引或數組中的鍵?

set -o nounset 

1)有一個索引數組,如:

myArray=("red" "black" "blue") 

這是檢查是否元素1設置最短的路?
我有時會使用以下方法:

test "${#myArray[@]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist" 

我想知道,如果有一個首選之一。

2)如何處理非連續索引?

myArray=() 
myArray[12]="red" 
myArray[51]="black" 
myArray[129]="blue" 

如何快速檢查'51'已被設置爲例如?

3)如何處理關聯數組?

declare -A myArray 
myArray["key1"]="red" 
myArray["key2"]="black" 
myArray["key3"]="blue" 

如何快速檢查'key2'已被使用爲例?

感謝

EDITED
最簡單的方法似乎對我說:

if test "${myArray['key_or_index']+isset}" 
    then 
     echo "yes" 
    else 
     echo "no" 
fi; 

這適用於這兩個索引和關聯數組。使用set -o nounset顯示沒有錯誤。
感謝doubleDown的headup。

回答

79

要檢查元件被設置(同時適用於索引和關聯數組)

[ ${array[key]+abc} ] && echo "exists" 

基本上什麼${array[key]+abc}確實是

  • 如果array[key]設置,返回abc
  • 如果array[key]沒有設置,返回任何


參考文獻:

  1. Parameter Expansion Bash中手工和小附註

    如果省略冒號,運營商測試僅適用於存在[的參數]

  2. 這個答案實際上是從答案適用於這太問題:How to tell if a string is not defined in a bash shell script


包裝函數:

exists(){ 
    if [ "$2" != in ]; then 
    echo "Incorrect usage." 
    echo "Correct usage: exists {key} in {array}" 
    return 
    fi 
    eval '[ ${'$3'[$1]+muahaha} ]' 
} 

例如

if ! exists key in array; then echo "No such array element"; fi 
+0

我這樣解決了:if test「$ {myArray ['key_or_index'] + isset}」;然後回顯「是」;否則回顯「否」;網絡連接;在我看來,這是最簡單的方法,它適用於索引和關聯數組。謝謝 –

+2

+1!感謝'$ {var + val}'符號!我再次閱讀「bash」,發現我之前跳過了! – TrueY

+1

@doubleDown如果[$ {array [key] + abc}]不存在,你如何在if子句中使用[$ {array [key] + abc}]來做某些事情? – olala

7

不幸的是,bash沒辦法區分undefined變量。

但是有一些方法:

$ array=() 
$ array[12]="red" 
$ array[51]="black" 
$ array[129]="blue" 

$ echo ${array[@]} 
red black blue 

$ echo ${!array[@]} 
12 51 129 

$ echo "${#array[@]}" 
3 

$ printf "%s\n" ${!array[@]}|grep -q ^51$ && echo 51 exist 
51 exist 

$ printf "%s\n" ${!array[@]}|grep -q ^52$ && echo 52 exist 

(沒有給出答案)

而對於關聯數組,你可以使用相同的:

$ unset array 
$ declare -A array 
$ array["key1"]="red" 
$ array["key2"]="black" 
$ array["key3"]="blue" 
$ echo ${array[@]} 
blue black red 

$ echo ${!array[@]} 
key3 key2 key1 

$ echo ${#array[@]} 
3 

$ set | grep ^array= 
array=([key3]="blue" [key2]="black" [key1]="red") 

$ printf "%s\n" ${!array[@]}|grep -q ^key2$ && echo key2 exist || echo key2 not exist 
key2 exist 

$ printf "%s\n" ${!array[@]}|grep -q ^key5$ && echo key5 exist || echo key5 not exist 
key5 not exist 

你可以做的工作,而不需要外部工具(沒有printf | grep as 純粹bash),爲什麼不,建立checkIfExist()作爲一個新的bash功能:

$ checkIfExist() { 
    eval 'local keys=${!'$1'[@]}'; 
    eval "case '$2' in 
     ${keys// /|}) return 0 ;; 
     *) return 1 ;; 
     esac"; 
} 

$ checkIfExist array key2 && echo exist || echo don\'t 
exist 

$ checkIfExist array key5 && echo exist || echo don\'t 
don't 

甚至創造一個新的getIfExist bash函數返回所需的值,並退出與假的結果碼如果不存在所需的值:

$ getIfExist() { 
    eval 'local keys=${!'$1'[@]}'; 
    eval "case '$2' in 
     ${keys// /|}) echo \${$1[$2]};return 0 ;; 
     *) return 1 ;; 
     esac"; 
} 

$ getIfExist array key1 
red 
$ echo $? 
0 

$ # now with an empty defined value 
$ array["key4"]="" 
$ getIfExist array key4 

$ echo $? 
0 
$ getIfExist array key5 
$ echo $? 
1 
+0

這是非常有趣的通過aaaall繼續。謝謝 –

4

在bash 39年3月4日測試(1)-release

declare -A fmap 
fmap['foo']="boo" 

key='foo' 
# should echo foo is set to 'boo' 
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi 
key='blah' 
# should echo blah is unset in fmap 
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi 
+0

當密鑰的值爲空字符串時失敗。作爲一種解決方法,您可以使用'+'參數擴展來用一些佔位符(如下劃線)替換空值。例如'declare -A a [x] =; [[$ {a [x]}]]; echo $?'打印'1',但是'declare -A a [x] =; [[$ {a [ x] + _}]]; echo $?'打印'0'。 – user4669748

0

Ť他是我爲腳本找到的最簡單的方法。

<search>是要查找的字符串,ASSOC_ARRAY的變量牽着你的關聯數組的名稱。

Dependign你想達到什麼:

項存在

if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key is present; fi 

項是否存在不

if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key not present; fi 

值存在

if grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value is present; fi 

值存在不

if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi 
1

我寫了一個函數,以檢查是否一個鍵在擊陣列存在:

# Check if array key exists 
# Usage: array_key_exists $array_name $key 
# Returns: 0 = key exists, 1 = key does NOT exist 
function array_key_exists() { 
    local _array_name="$1" 
    local _key="$2" 
    local _cmd='echo ${!'$_array_name'[@]}' 
    local _array_keys=($(eval $_cmd)) 
    local _key_exists=$(echo " ${_array_keys[@]} " | grep " $_key " &>/dev/null; echo $?) 
    [[ "$_key_exists" = "0" ]] && return 0 || return 1 
} 

declare -A my_array 
my_array['foo']="bar" 

if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then 
    echo "OK" 
else 
    echo "ERROR" 
fi 

GNU bash中,版本4.1.5(1)-release(1486-PC-Linux的GNU)測試

3

從人bash中,條件式:

-v varname 
       True if the shell variable varname is set (has been assigned a value). 

例如:

declare -A foo 
foo[bar]="this is bar" 
foo[baz]="" 
if [[ -v "foo[bar]" ]] ; then 
    echo "foo[bar] is set" 
fi 
if [[ -v "foo[baz]" ]] ; then 
    echo "foo[baz] is set" 
fi 
if [[ -v "foo[quux]" ]] ; then 
    echo "foo[quux] is set" 
fi 

這將顯示foo [bar]和foo [baz]都被設置(儘管後者設置爲空值)並且foo [quux]不是。

相關問題