অ্যারে নামের অংশ হিসাবে কীভাবে ভেরিয়েবল ব্যবহার করবেন


11

আমার দুটি অ্যারে রয়েছে:

arrayA=(1 2 3)
arrayB=(a b c)

এবং আমি তাদের মধ্যে একটি কমান্ড লাইন আর্গুমেন্ট, অর্থাত্, ছাড়াই মুদ্রণ করতে চাই if else

আমি সিনট্যাক্সে কোনও সাফল্য ছাড়াই কয়েকটি ভিন্নতার চেষ্টা করেছি। আমি এই জাতীয় কিছু করতে চাই:

ARG="$1"

echo ${array${ARG}[@]}

তবে আমি একটি "খারাপ প্রতিস্থাপন" ত্রুটি পেয়েছি। আমি কীভাবে এটি অর্জন করতে পারি?


এই প্রবলভাবে হয় না কথ্য ব্যাশ। দয়া করে, এটি করবেন না।
ওয়াইল্ডকার্ড

উত্তর:


22

এটি করার চেষ্টা করুন:

$ arrayA=(1 2 3)
$ x=A
$ var=array$x[@]
$ echo ${!var}
1 2 3

বিঃদ্রঃ

  • থেকে man bash(প্যারামিটার সম্প্রসারণ):
    ${parameter}
           The value of parameter is substituted.
 The braces are required when parameter is a positional parameter with
  more than one

অঙ্ক, বা যখন প্যারামিটার একটি অক্ষর দ্বারা অনুসরণ করা হয় যা এর নামের অংশ হিসাবে ব্যাখ্যা করা যায় না।
* যদি প্যারামিটারের প্রথম অক্ষরটি একটি বিস্মৃত বিন্দু (!) হয় তবে ভ্যারিয়েবল ইন্ডিরেশনের একটি স্তর চালু করা হয়। বাশ অন্যান্য প্যারামিটার থেকে গঠিত ভেরিয়েবলের মানটি ভেরিয়েবলের নাম হিসাবে ব্যবহার করে; এই পরিবর্তনশীলটি তখন প্রসারিত হয় এবং সেই মানটি প্যারামিটারের মানের পরিবর্তে বাকী বিকল্পে ব্যবহৃত হয়। এটি পরোক্ষ সম্প্রসারণ হিসাবে পরিচিত। * এর ব্যতিক্রমগুলি নীচে বর্ণিত। {! উপসর্গ *} এবং $ {! নাম [@]। এর বিস্তৃতি। উদ্বোধন পয়েন্টটি অবিলম্বে দিকনির্দেশ প্রবর্তনের জন্য বামবন্ধনী বন্ধনী অনুসরণ করতে হবে।


ভেরিয়েবলের !সামনে ঠিক কী করছে var? কীভাবে এটি কাজ করে, এটি গুগলিংয়ের ইতিহাস প্রতিস্থাপন বলে মনে হয়েছিল, কিন্তু এখানে কীভাবে কাজ হয়েছে তা আমি দেখতে পেলাম না।
হারুন

আমার সম্পাদিত পোস্টটি দেখুন
গিলস কুইনট

4

আপনি অন্য উত্তরে নির্দেশিত হিসাবে অপ্রত্যক্ষ অ্যাক্সেস ব্যবহার করতে পারবেন , অন্য উপায় (ksh এবং বাশ 4.3 এবং আরও নতুন ক্ষেত্রে) নেম্রেফ ব্যবহার করা হবে। বিশেষত অ্যারেগুলির ক্ষেত্রে এটি আরও কার্যকর হতে পারে যেহেতু আপনি নামেরফের মাধ্যমে অ্যারেটিকে সূচক করতে পারেন এবং রেফারেন্স হিসাবে ব্যবহৃত ভেরিয়েবলের সূচকটি লাগানোর দরকার নেই।

arr1=(a b c)
arr2=(x y z)
typeset -n p=arr1    # or 'declare -n' 
echo "${p[1]}"       # prints 'b'

এটি পরোক্ষ অ্যাক্সেসের মাধ্যমে কাজ করে না:

q=arr2
echo "${!q}"         # prints 'x', the same as $arr2
echo "${!q[1]}"      # doesn't work, it tries to take q[1] as a reference

একজন সি প্রোগ্রামার ${!q[1]}যেমন এটি রাখতে পারে, এখানে এটি qবিন্যাসের অ্যারে হিসাবে বিন্যাসের পরিবর্তে কাজ করে poin



1
arrayA=(1 2 3)
arrayB=(a b c)

ARG="$1"

eval echo \${array${ARG}[@]}

dataget (){ 
    eval echo \${array${1}[${2:-@}]}
}
$ dataget A
1 2 3
$ dataget A 0
1
$ dataget B 1
b

নোট: স্পেস ক্ষেত্রে cotes পালাতে !

eval dostuff \"\${array${1}[${2:-@}]}\"

1

এটি অনেক পরীক্ষা এবং ত্রুটি নিয়েছে কিন্তু শেষ পর্যন্ত কাজ করেছে।

আমি ইউনেসের কাছ থেকে কিছুটা অনুপ্রেরণা নিয়েছি। তবে অন্য সমস্ত উত্তর আমার পুরানো বাশকে সহায়তা করে নি (suse11sp1 [৩.২.৫১ (১) -আর দয়া করে])

'ফর' লুপ অপ্রত্যক্ষ অ্যারে প্রসারিত করতে অস্বীকৃতি জানিয়েছে, পরিবর্তে আপনাকে এটির পূর্ব-প্রসারণ করা দরকার, এটি আপনার নতুন ভেরিয়েবল নামের সাথে অন্য অ্যারে তৈরি করতে ব্যবহার করুন। নীচে আমার উদাহরণটি একটি ডাবল লুপ দেখায়, এটি হ'ল আমার ব্যবহার।

THEBIGLOOP=(New_FOO New_BAR)

FOOthings=(1 2 3)
BARthings=(a b c)

for j in ${THEBIGLOOP[*]}
do
    TheNewVariable=$(eval echo \${${j#New_}things[@]})

    for i in $TheNewVariable
        do
            echo  $j $i" hello"
        echo
    done
done

আমি প্রথম অ্যারে এন্ট্রি থেকে "নতুন_" মুছতে, তারপরে "জিনিসগুলি" দিয়ে কনটেন্টেট করে, "ফুথিংস" পেতে # ব্যবহার করছি। প্রতিধ্বনি এবং ইওল সহ \ $ {}, তারপরে ত্রুটি নিক্ষেপ না করে তাদের কাজটি করুন, যা একটি নতুন $ () এ মোড়ানো থাকে এবং নতুন ভেরিয়েবলের নাম নির্ধারিত হয়।

$ Test.sh

New_FOO 1 hello

New_FOO 2 hello

New_FOO 3 hello

New_BAR a hello

New_BAR b hello

New_BAR c hello
আপডেট ##### 2018/06/07

আমি সম্প্রতি এই বিষয়ে আরও একটি স্পিন আবিষ্কার করেছি। তৈরি ভেরিয়েবল আসলে একটি অ্যারে নয়, একটি স্পেস ডিলিমিট স্ট্রিং। উপরের কাজটি ঠিক ছিল কারণ "কীভাবে" কাজ করে, এটি অ্যারেটি পড়ে না, এটি প্রসারিত হয় এবং তারপরে লুপ করা হয়, নীচের সূচনাটি দেখুন:

for VARIABLE in 1 2 3 4 5 .. N
do
    command1
    command2
    commandN
done

তবে, আমার তখন এটি অ্যারে হিসাবে ব্যবহার করা দরকার। এর জন্য আমার আরও একটি পদক্ষেপ করা দরকার। আমি ডেনিস উইলিয়ামসনের কোড ভারব্যাটিম নিয়েছি । আমি এটি পরীক্ষা করেছি এবং এটি ভাল কাজ করে।

IFS=', ' read -r -a TheNewVariable <<< ${TheNewVariable[@]}

"আইএফএস = ','" হ'ল একটি পরিবর্তনশীল যা আপনার ডিলিমিনেটর ধারণ করে। "-a" কাট দিয়ে "পড়ুন" এবং অ্যারে ভেরিয়েবলের মধ্যে স্টিং ফিড করে। মনে রাখবেন, এই উদ্ধৃতি চিহ্ন তার কোন সম্মান আছে, কিন্তু সেখানে কয়েকটি বিকল্প রইল পঠিত এই পরিচালনা করতে, যেমন আমি -r পতাকা যা আমি না হলেই ভাল হত সরিয়েছি। সুতরাং আমি এখন ভেরিয়েবল তৈরিতে এই সংযোজনটি সংযুক্ত করেছি, যা ডেটাটিকে যেমন করা উচিত তেমন আচরণ করা এবং সম্বোধন করার অনুমতি দেয়।

THEBIGLOOP=(New_FOO New_BAR)

FOOthings=(1 2 3)
BARthings=(a b c)

for j in ${THEBIGLOOP[*]}
do

    IFS=', ' read -a TheNewVariable <<< $(eval echo \${${j#New_}things[@]})

    for i in ${TheNewVariable[@]}  #Now have to wrap with {} and expand with @
        do
            echo  $j $i" hello"
            echo  ${TheNewVariable[$i]}  #This would not work in the original code
        echo
    done
done

0

এভাবেই আপনি একটি গতিশীল নামযুক্ত ভেরিয়েবল তৈরি করবেন (বাশ সংস্করণ <4.3)।

# Dynamically named array
my_variable_name="dyn_arr_names"
eval $my_variable_name=\(\)

# Adding by index to the array eg. dyn_arr_names[0]="bob"
eval $my_variable_name[0]="bob"

# Adding by pushing onto the array eg. dyn_arr_names+=(robert)
eval $my_variable_name+=\(robert\)

# Print value stored at index indirect
echo ${!my_variable_name[0]}

# Print value stored at index
eval echo \${$my_variable_name[0]}

# Get item count
eval echo \${#$my_variable_name[@]}

নীচে ফাংশনগুলির একটি গ্রুপ রয়েছে যা ডায়নামিকভাবে নামযুক্ত অ্যারেগুলি পরিচালনা করতে ব্যবহার করা যেতে পারে (বাশ সংস্করণ <4.3)।

# Dynamically create an array by name
function arr() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
     # The following line can be replaced with 'declare -ag $1=\(\)'
     # Note: For some reason when using 'declare -ag $1' without the parentheses will make 'declare -p' fail
    eval $1=\(\)
}

# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    eval $1[\$\(\(\${#${1}[@]}\)\)]=\$2
}

# Update an index by position
function arr_set() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    eval ${1}[${2}]=\${3}
}

# Get the array content ${array[@]}
function arr_get() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    eval echo \${${1}[@]}
}

# Get the value stored at a specific index eg. ${array[0]}  
function arr_at() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    [[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
    local v=$1
    local i=$2
    local max=$(eval echo \${\#${1}[@]})
    # Array has items and index is in range
    if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
    then 
        eval echo \${$v[$i]}
    fi
}

# Get the value stored at a specific index eg. ${array[0]}  
function arr_count() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    local v=${1}
    eval echo \${\#${1}[@]}
}



array_names=(bob jane dick)

for name in "${array_names[@]}"
do
    arr dyn_$name
done

echo "Arrays Created"
declare -a | grep "a dyn_"

# Insert three items per array
for name in "${array_names[@]}"
do
    echo "Inserting dyn_$name abc"
    arr_insert dyn_$name "abc"
    echo "Inserting dyn_$name def"
    arr_insert dyn_$name "def"
    echo "Inserting dyn_$name ghi"
    arr_insert dyn_$name "ghi"
done

for name in "${array_names[@]}"
do
    echo "Setting dyn_$name[0]=first"
    arr_set dyn_$name 0 "first"
    echo "Setting dyn_$name[2]=third"
    arr_set dyn_$name 2 "third"
done 

declare -a | grep "a dyn_"

for name in "${array_names[@]}"
do
    arr_get dyn_$name
done


for name in "${array_names[@]}"
do
    echo "Dumping dyn_$name by index"
    # Print by index
    for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
    do
        echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"

    done
done

for name in "${array_names[@]}"
do
    echo "Dumping dyn_$name"
    for n in $(arr_get dyn_$name)
    do
        echo $n
    done
done

নীচে ফাংশনগুলির একটি গ্রুপ রয়েছে যা গতিশীলভাবে নামযুক্ত অ্যারেগুলি পরিচালনা করতে ব্যবহার করা যেতে পারে (বাশ সংস্করণ> = 4.3)।

# Dynamically create an array by name
function arr() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -g -a $1=\(\)   
}

# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    declare -n r=$1
    r[${#r[@]}]=$2
}

# Update an index by position
function arr_set() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    declare -n r=$1 
    r[$2]=$3
}

# Get the array content ${array[@]}
function arr_get() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    declare -n r=$1 
    echo ${r[@]}
}

# Get the value stored at a specific index eg. ${array[0]}  
function arr_at() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    [[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
    declare -n r=$1 
    local max=${#r[@]}
    # Array has items and index is in range
    if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
    then 
        echo ${r[$2]}
    fi
}

# Get the value stored at a specific index eg. ${array[0]}  
function arr_count() {
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
    declare -p "$1" > /dev/null 2>&1
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; }
    declare -n r=$1
    echo ${#r[@]}
}



array_names=(bob jane dick)

for name in "${array_names[@]}"
do
    arr dyn_$name
done

echo "Arrays Created"
declare -a | grep "a dyn_"

# Insert three items per array
for name in "${array_names[@]}"
do
    echo "Inserting dyn_$name abc"
    arr_insert dyn_$name "abc"
    echo "Inserting dyn_$name def"
    arr_insert dyn_$name "def"
    echo "Inserting dyn_$name ghi"
    arr_insert dyn_$name "ghi"
done

for name in "${array_names[@]}"
do
    echo "Setting dyn_$name[0]=first"
    arr_set dyn_$name 0 "first"
    echo "Setting dyn_$name[2]=third"
    arr_set dyn_$name 2 "third"
done 

declare -a | grep 'a dyn_'

for name in "${array_names[@]}"
do
    arr_get dyn_$name
done


for name in "${array_names[@]}"
do
    echo "Dumping dyn_$name by index"
    # Print by index
    for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
    do
        echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"

    done
done

for name in "${array_names[@]}"
do
    echo "Dumping dyn_$name"
    for n in $(arr_get dyn_$name)
    do
        echo $n
    done
done

এই উদাহরণগুলির আরও তথ্যের জন্য লুডভিক জেরাব্যাকের ডায়নামিক অ্যারে দ্বারা বাশিং নেওয়া দেখুন


1
আমি কৌতূহল বোধ করি কেন এটি নিম্নমানের হয়। পদ্ধতির সাথে কিছু ভুল / বিপজ্জনক আছে কি? বাশ <4.3 এ ফাংশন ব্যবহার করতে চাই।
স্টেফেন্ম

আমি আপনার পোস্টের প্রশংসা করি, আমি দরকারী তথ্য এবং বিশেষত "আইটেম গণনা পান" নির্দেশনাটি পেয়েছি: ইভাল প্রতিধ্বনি \ $ {# $ আমার_ভরিবেবল_নাম [@]}
ড্যানিয়েল পেরেজ

-1

কোনভাবেই না :(

যদি আপনার অ্যারেগুলি সরল হয় তবে এসোসিয়েটিভ অ্যারেগুলি ব্যবহার করুন

    declare -A array
    array[A]="1 2 3"
    array[B]="a b c"

দুর্ভাগ্যক্রমে, যদি আপনার অ্যারেগুলি আরও জটিল হয় (উদাহরণস্বরূপ array=( "a b" c )), এটি কার্যকর হবে না। তারপরে, আপনার লক্ষ্যে পৌঁছানোর জন্য আপনাকে আরও একটি উপায় সম্পর্কে আরও কঠোর চিন্তা করতে হবে।


ডাউনটোটের কারণ কী? এসোসিয়েটিভ অ্যারে সমস্ত কিছুকে গ্রুপ করার একটি দুর্দান্ত উপায় সরবরাহ করে, ধরে নিই যে আমার উপাদানগুলির মধ্যে কোনও স্থান থাকবে না।
হারুন

2
@ অ্যারন ধরে নিচ্ছেন যে আপনার উপাদানগুলিতে স্পেস নেই that এটি যুক্তিসঙ্গত নকশা design ওয়াটায়েল আমি অনুমান করি যে উত্তরটি "কোনও উপায় নয়" দিয়ে শুরু করা যখন আপনার প্রশ্নের প্রাথমিক ফোকাসটি স্পষ্টভাবে সম্ভব তখন কোনও ভাল ধারণা ছিল না।
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

-1

ব্যবহার eval

arrayA=(1 2 3)
ARG=arrayA
eval echo \${$ARG[@]} # equivalent to eval echo \${arrayA[@]}
                      # note that we escape the first '$' to prevent from 
                      # its parameter expansion before passing it to echo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.