প্রশ্নের সংক্ষিপ্ত বিবৃতি:
অ্যারেটির সম্পূর্ণ অনুলিপি তৈরি করা বা ব্যবহার না করেই বাশ অ্যারেতে উপাদানগুলির সংখ্যা গণনা করার জন্য কি অন্তর্নির্মিত বাশ পদ্ধতি রয়েছে eval
?
অধিক তথ্য:
ব্যাশ প্যারামিটার প্রতিস্থাপন ব্যবহার করে, কেউ নিম্নলিখিতটি করতে পারেন:
- একটি অ্যারের দৈর্ঘ্য নির্ধারণ:
myArr=(A B C); echo ${#myArr[@]}
। - অপ্রত্যক্ষভাবে নাম দ্বারা একটি পরিবর্তনশীল রেফারেন্স:
NAME=myVar; echo ${!NAME}
(এটি অ্যারে উপাদানগুলির জন্যও প্রযোজ্য):
NAME=myArr[1]; echo ${!NAME}
তবে যদি একটি অ্যারের নাম অন্য ভেরিয়েবলে সংরক্ষণ করা হয় তবে কীভাবে অ্যারেতে উপাদানগুলির সংখ্যা নির্ধারণ করা যায়? ( উপরের দুটি পরামিতি বিকল্পের সংমিশ্রণের বিষয়টি কেউ বিবেচনা করতে পারে )) উদাহরণস্বরূপ:
myArr=(A B C D)
NAME=myArr
# Get the number of elements in the array indirectly referenced by NAME.
count=${#$NAME[@]} # This syntax is invalid. What is the right way?
নীচে একাধিক প্রচেষ্টা রয়েছে যা সমস্ত ব্যর্থ:
# Setup for following attempts:
myArr=(A B C D)
NAME=myArr
EXPR1=$NAME[@] # i.e. EXPR1='myArr[@]'
EXPR2=#$NAME[@] # i.e. EXPR2='#myArr[@]'
# Failed attempts to get the lengh of the array indirectly:
1. count=${#$NAME[@]} # ERROR: bash: ...: bad substitution
2. count=${#!EXPR1} # ERROR: bash: !EXPR}: event not found
3. count=${#\!EXPR1} # ERROR: bash: ...: bad substitution
4. count=${!#EXPR1} # ERROR: bash: ...: bad substitution
5. count=${!EXPR2} # Returns NULL
আমি উপরোক্ত কিছু অন্যান্য রূপও চেষ্টা করে দেখেছি, তবে এটির ব্যতীত এখনও কার্যকর কিছু খুঁজে পেলাম না: (ক) অ্যারের একটি অনুলিপি তৈরি করে বা (বি) ব্যবহার করে eval
।
কাজের পদ্ধতি:
এটি সমাধানের কয়েকটি উপায় রয়েছে যা সম্ভবত অনুকূল নয় (তবে আমি ভুল হলে আমাকে সংশোধন করুন):
পদ্ধতি 1: অ্যারে অনুলিপি করুন
অ্যারেটিকে অন্য কোনও (স্থির-নামযুক্ত) ভেরিয়েবলকে বরাদ্দ করুন এবং এতে উপাদানগুলির সংখ্যা পান।
EXPR=$NAME[@]
arrCopy=( "${!EXPR}" )
count=${#arrCopy}
পদ্ধতি 2: ব্যবহার করুন eval
EXPR="count=\${#$NAME[@]}" # i.e. 'count=${myArr[@]}'
eval $EXPR
# Now count is set to the length of the array
সারসংক্ষেপ:
বাশ্রে পরোক্ষভাবে কোন অ্যারের দৈর্ঘ্য নির্ধারণের জন্য কোনও বিল্ট-ইন পদ্ধতি (অর্থাত্ প্যারামিটার সাবস্টিটিউশন সিনট্যাক্স) রয়েছে? যদি তা না হয় তবে এটি করার সবচেয়ে দক্ষ উপায় কোনটি? আমি ধরে নিলাম এটি eval
উপরের পদ্ধতি, তবে সেখানে সুরক্ষা বা পারফরম্যান্সের সমস্যা আছে eval
কি?
time bash -c 'a=(1 a +); c=a; for ((i=0;i<100000;i++)); do eval "echo \${#$c[@]}"; done' > /dev/null
এবং একইভাবে e=$c[@]; d=("${!e}); echo ${#d[@]}
লুপে। এই কপিটি অনুলিপি করে নেওয়া প্রায় 90% সময় নিয়েছিল। এবং আমি অনুমান করি যে ব্যবধানটি কেবল বৃহত্তর অ্যারে এবং এর উপাদানগুলি বাড়িয়ে তুলবে।