जवाबों:
बैश 4 में, आप सहयोगी सरणियों का उपयोग कर सकते हैं:
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
आरंभ में आप सेट अप करने के लिए भी सीधे कार्य कर सकते हैं:
array[foo]=1
array[bar]=1
# etc.
या इस तरह:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
सरल है, लेकिन एक समस्या है: यह काम नहीं करेगा यदि आप set -u
अपनी स्क्रिप्ट में उपयोग करते हैं (जो अनुशंसित है), जैसा कि आपको "अनबाउंड चर" मिलेगा।
set -u
: davidpashley.com/articles/writing-robust-shell-scripts.html , blog.hashbang0.com/2010/05/18/robust-bash-scripts-part-one , openews.net//12-bash- लिपि-से-लेखन-मजबूत ।
यह एक पुराना प्रश्न है, लेकिन मुझे लगता है कि जो सबसे सरल उपाय है वह अभी तक सामने नहीं आया है test ${array[key]+_}
:। उदाहरण:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
आउटपुट:
a is set
b is set
कैसे यह काम की जाँच को देखने के लिए इस ।
env
उपनाम, प्रोज और अन्य कार्यों में अस्पष्टता से बचने के लिए उपयोग करने की सिफारिश की है, जिन्होंने "परीक्षण" नाम को अपनाया हो सकता है। जैसा ऊपर है env test ${xs[a]+_} && echo "a is set"
। आप डबल-ब्रैकेट का उपयोग करके भी यह कार्यक्षमता प्राप्त कर सकते हैं, एक ही चाल फिर अशक्त के लिए जाँच:[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
यह जांचने का एक तरीका है कि क्या एक साहचर्य सरणी का एक तत्व मौजूद है (सेट नहीं है), यह खाली से अलग है:
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
फिर इसका उपयोग करें:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
if ! some_check then return 1
= some_check
। तो: isNotSet() { [[ ... ]] }
। नीचे मेरे समाधान की जांच करें, आप इसे एक साधारण जांच में कर सकते हैं।
आप देख सकते हैं कि ऐरे की सामग्री को grep में दर्ज करके कोई प्रविष्टि मौजूद है या नहीं।
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
आप grep -n के साथ एक प्रविष्टि का सूचकांक भी प्राप्त कर सकते हैं, जो एक मैच की लाइन नंबर (शून्य-आधारित सूचकांक प्राप्त करने के लिए 1 को घटाना याद रखें) यह बहुत बड़ी सरणियों को छोड़कर यथोचित त्वरित होगा।
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
स्पष्टीकरण:
$( ... )
एक चर में एक कमांड के उत्पादन पर कब्जा करने के लिए backticks का उपयोग करने के समान है printf
प्रति पंक्ति एक तत्व mydata को आउटपुट करता है @
के बजाय *.
2 लाइनों में इस टाल बंटवारे "हैलो दुनिया")grep
सटीक स्ट्रिंग की खोज: ^
और $
लाइन की शुरुआत और अंत से मेल खाते हैंgrep -n
रिटर्न लाइन #, 4 के रूप में: हैलो दुनिया grep -m 1
केवल पहला मैच पाता हैcut
सिर्फ लाइन नंबर निकालता है आप निश्चित रूप से घटाव को कमांड में मोड़ सकते हैं। लेकिन फिर लापता के लिए -1 का परीक्षण करें:
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
पूर्णांक अंकगणित करता हैमुझे नहीं लगता कि आप इसे ठीक से लूपिंग के बिना कर सकते हैं जब तक कि आपके पास सरणी में बहुत सीमित डेटा न हो ।
यहां एक सरल संस्करण है, यह सही ढंग से कहेगा कि "Super User"
सरणी में मौजूद है। लेकिन यह भी कहा जाएगा कि "uper Use"
यह सरणी में है।
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
समस्या यह है कि एंकर को जोड़ने का कोई आसान तरीका नहीं है (जो मैं सोच सकता हूं) सरणी के माध्यम से लूप करने के अलावा। जब तक आप उन्हें सरणी में डालने से पहले जोड़ सकते हैं ...
grep "\b$FINDME\b"
)। संभवतः गैर-अल्फ़ान्यूमेरिक स्थिरांक के साथ काम कर सकता है, जिसमें कोई रिक्त स्थान नहीं है, "(^| )$FINDME(\$| )"
(या ऐसा कुछ ... मैं कभी भी यह जानने में सक्षम नहीं हुआ कि regexp grep का क्या स्वाद उपयोग करता है।)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array
। चीयर्स
${ARRAY[@]}
इस्तेमाल किया जाना चाहिए।