ডিরিফারেন্স কনটেনেটেড ভেরিয়েবলের নাম


12

আমি এটি করতে পারি, তবে এর জন্য ভেরিয়েবলের একটি স্ট্রিং তৈরি করতে হবে তারপরে এটি ডিফারেন্সিং। এটি সরল বিবৃতিতে সংক্ষিপ্ত করার কোনও উপায় আছে কি?

#!/bin/bash

FRUITS="BANANA APPLE ORANGE"

BANANA_COLOUR="Yellow"
APPLE_COLOUR="Green or Red"
ORANGE_COLOUR="Blue"

for fruit in $( echo $FRUITS ); do
    fruit_colour="${fruit}_COLOUR"
    echo $fruit is ${!fruit_colour}
done

আমি অনেকগুলি জিনিস যেমন ${!"${fruit}_COLOUR"}বা \$${fruit}_COLOURঅন্যান্য বিভিন্ন রূপ চেষ্টা করেছি, তবে কেবলমাত্র উপায়টি স্ট্রিং ব্যবহার করে।


!সিনট্যাক্স পরিবর্তনশীল প্রতিকল্পন উপর একটি পতাকা মূলত বলছেন যে "বিকল্প দুইবার" হয়। এটি প্রয়োজনীয়তার পরিবর্তন করে না যে প্রান্তের ভিতরে যা আছে ${…}অবশ্যই একটি পরিবর্তনশীল নাম হতে পারে। সুতরাং না, আপনি নাম সহ এমন একটি ভেরিয়েবল ব্যবহার এড়াতে পারবেন না, যদি না আপনি ভিন্ন পদ্ধতি ( eval) ব্যবহার করেন।
গিলস 'অশুভ হওয়া বন্ধ করুন'

আপনি আরও অনেক পরিষ্কারভাবে এটি করতে সাহসী অ্যারে ব্যবহার করতে পারেন। তবে এটি আপনার প্রশ্নের সরাসরি উত্তর নয়, সুতরাং এটি একটি মন্তব্য হিসাবে যুক্ত করুন।
প্যাট্রিক

উত্তর:


11

প্রথমত, আপনি ব্যবহার করতে প্রয়োজন হবে না $(echo $FRUITS)যে forবিবৃতি। জাস্ট ব্যবহার $FRUITSকরা যথেষ্ট। তারপরে আপনি লুপের অভ্যন্তরে যে কোনও একটি লাইন ব্যবহার করতে পারেন eval

evalকেবল ব্যাশ বলে একটি দ্বিতীয় করতে মূল্যায়ন (অর্থাত আরো এক তার স্বাভাবিক মূল্যায়ন বেশি) নিম্নোক্ত বিবৃতি করুন। \$প্রথম মূল্যায়ন প্রাণে বেঁচে যান $এবং পরবর্তী মূল্যায়ন তারপর এই একইরূপে $একটি পরিবর্তনশীল নাম শুরুর, যেমন যেটি "ইয়েলো", ইত্যাদি সমাধান করা

এইভাবে আপনার একটি পৃথক পদক্ষেপের প্রয়োজন হবে না যা একটি অন্তর্বর্তীকালীন স্ট্রিং তৈরি করে (যা আমি বিশ্বাস করি যে আপনার প্রশ্নের মূল উদ্দেশ্য)।

for fruit in $FRUITS ;do
    eval echo $fruit is \$${fruit}_COLOUR
done

বিকল্প পদ্ধতির জন্য, যেমনটি প্যাট্রিক একটি মন্তব্যে উল্লিখিত হয়েছে (উপরে), আপনি পরিবর্তে একটি এসোসিয়েটিভ অ্যারে ব্যবহার করতে পারেন , যাতে কোনও উপাদানের সূচককে পূর্ণসংখ্যার প্রয়োজন হয় না। আপনি কোনও স্ট্রিং ব্যবহার করতে পারেন, যেমন এক ধরণের ফলের নাম। বাশের সহযোগী অ্যারে ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হল:

# This declares an associative array (It unsets it if it already exists)
declare -A colour
colour['BANANA']="Yellow"
colour["APPLE"]="Green or Red"
colour[MARTIAN ORANGE]="Blue"

for fruit in BANANA APPLE "MARTIAN ORANGE" ;do 
    echo "$fruit" is "${colour[$fruit]}"
done

6

আপনি এটি করতে ব্যাশ-বিল্টিন ব্যবহার করতে পারেন eval:

#!/bin/bash
FRUITS="BANANA APPLE ORANGE"
BANANA_COLOUR="Yellow"
APPLE_COLOUR="Green or Red"
ORANGE_COLOUR="Blue"

for fruit in $( echo $FRUITS );
do
    fruit_colour=${fruit}_COLOUR
    eval echo $fruit is \$${fruit_colour}
done

ব্যাকস্ল্যাশড-ডলার সাইন নোট করুন। মূলত, "ইভাল" লাইনটি bash পরিবর্তনের জন্য $fruitএবং ${fruit_color}তারপরে, evalকল করার আগে দ্বিতীয় দফা বিকল্পটি ব্যবহার করে echo


1

আপনার একটি স্পষ্ট বিবৃতি দরকার নেই। evalবেশিরভাগ ভাষায় ইঙ্গিত হ'ল আপনি কিছু ভুল করছেন।

foo_var=10
bar_var=12

# Build a string with your var name of choice
chosen_prefix='foo'
var_name="${chosen_prefix}_var"

# Use bang to deference it
chossen_value=${!var_name}
echo "Chossen value: ${chossen_value}"

আমি এটি যুক্তিযুক্ত ব্যবহার করাই নিরাপদ evalকারণ কমপক্ষে লোকেরা জানে যে এটি বিপজ্জনক, ${!var}এটি প্রায় বিপজ্জনক bash( $chosen_prefixআক্রমণকারীর নিয়ন্ত্রণে থাকলে কমান্ড ইনজেকশন দুর্বলতাও ) এবং খুব কম লোকই এটি সম্পর্কে সচেতন। ব্যবহার করে দেখুন var_name='a[$(uname>&2)0]' bash -c 'v=${!var_name}'। এখানে সেরা পদ্ধতির সংস্থানীয় অ্যারে।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.