উত্তর:
আমি লিখিত হিসাবে প্রশ্নের উত্তর দিয়েছি, এবং এই কোড অ্যারে বিপরীত। (অ্যারেটিকে উল্টিয়ে না দিয়ে উপাদানগুলি বিপরীত ক্রমে মুদ্রণ করা for
শেষ উপাদান থেকে শূন্যের নিচে গণনা করা একটি লুপ মাত্র )) এটি একটি স্ট্যান্ডার্ড "প্রথম এবং শেষ" অ্যালগরিদম is
array=(1 2 3 4 5 6 7)
min=0
max=$(( ${#array[@]} -1 ))
while [[ min -lt max ]]
do
# Swap current first and last elements
x="${array[$min]}"
array[$min]="${array[$max]}"
array[$max]="$x"
# Move closer
(( min++, max-- ))
done
echo "${array[@]}"
এটি বিজোড় এবং এমনকি দৈর্ঘ্যের অ্যারেগুলির জন্য কাজ করে।
অপর একটি প্রচলিত পদ্ধতি:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
আউটপুট:
7 6 5 4 3 2 1
যদি extdebug
সক্ষম করা BASH_ARGV
থাকে তবে অ্যারে কোনও ফাংশনে বিপরীত ক্রমে সমস্ত অবস্থানগত পরামিতি ধারণ করে।
প্রচলিত পদ্ধতি (সমস্ত শুদ্ধ নয়) bash
):
যদি অ্যারের সমস্ত উপাদানগুলি কেবলমাত্র একটি অক্ষর হয় (প্রশ্নের মতো) আপনি ব্যবহার করতে পারেন rev
:
echo "${array[@]}" | rev
অন্যথায়:
printf '%s\n' "${array[@]}" | tac | tr '\n' ' '; echo
এবং যদি আপনি ব্যবহার করতে পারেন zsh
:
echo ${(Oa)array}
tac
, cat
মনে রাখা বেশ বিপরীত হিসাবে , ধন্যবাদ!
rev
উল্লেখ করতে rev
হবে যে দুটি সংখ্যার সংখ্যার জন্য সঠিকভাবে কাজ করবে না। উদাহরণস্বরূপ 12
রেভ ব্যবহারের একটি অ্যারের উপাদান হিসাবে মুদ্রিত হবে 21
। এটি ব্যবহার করে দেখুন ;-)
আপনি যদি আসলে অন্য অ্যারেতে বিপরীতটি চান:
reverse() {
# first argument is the array to reverse
# second is the output array
declare -n arr="$1" rev="$2"
for i in "${arr[@]}"
do
rev=("$i" "${rev[@]}")
done
}
তারপর:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
দেয়:
4 3 2 1
এটি অ্যারে সূচক অনুপস্থিত রয়েছে এমন ক্ষেত্রে সঠিকভাবে পরিচালনা করতে হবে, বলুন যে আপনার array=([1]=1 [2]=2 [4]=4)
ক্ষেত্রে 0 থেকে সর্বোচ্চ সূচীতে লুপিং অতিরিক্ত, খালি, উপাদান যুক্ত করতে পারে।
shellcheck
দুটি সতর্কতা প্রিন্ট করে: array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
এবং এর জন্য:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
declare
লাইন।
declare -n
4.3 এর আগে ব্যাশ সংস্করণগুলিতে কাজ করবে না।
জায়গায় অ্যারে অবস্থানগুলি অদলবদল করতে (এমনকি বিরল অ্যারে সহ) (বাশ 3.0.০ থেকে):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=101 [6]=202 [10]=303 [11]=404 [20]=505 [21]=606 [40]=707)
echo "Initial array values"
declare -p array
swaparray(){ local temp; temp="${array[$1]}"
array[$1]="${array[$2]}"
array[$2]="$temp"
}
ind=("${!array[@]}") # non-sparse array of indexes.
min=-1; max="${#ind[@]}" # limits to one before real limits.
while [[ min++ -lt max-- ]] # move closer on each loop.
do
swaparray "${ind[min]}" "${ind[max]}" # Exchange first and last
done
echo "Final Array swapped in place"
declare -p array
echo "Final Array values"
echo "${array[@]}"
ফাঁসি কার্যকর:
./script
Initial array values
declare -a array=([5]="101" [6]="202" [10]="303" [11]="404" [20]="505" [21]="606" [40]="707")
Final Array swapped in place
declare -a array=([5]="707" [6]="606" [10]="505" [11]="404" [20]="303" [21]="202" [40]="101")
Final Array values
707 606 505 404 303 202 101
পুরানো বাশের জন্য, আপনাকে লুপ ব্যবহার করতে হবে (ব্যাশে (2.04)) এবং $a
পিছনের স্থানটি এড়াতে ব্যবহার করতে হবে:
#!/bin/bash
array=(101 202 303 404 505 606 707)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s' "$a" "${array[i]}"
a=" "
done
echo
২.০৩ সাল থেকে ব্যাশের জন্য:
#!/bin/bash
array=(101 202 303 404 505 606 707)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
এছাড়াও (বিটওয়াইস নেগেশন অপারেটর ব্যবহার করে) (যেহেতু ব্যাশ ৪.২++):
#!/bin/bash
array=(101 202 303 404 505 606 707)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
কুরুচিপূর্ণ, অবিস্মরণীয়, তবে ওয়ান-লাইনার:
eval eval echo "'\"\${array['{$((${#array[@]}-1))..0}']}\"'"
eval eval echo "'\"\${array[-'{1..${#array[@]}}']}\"'"
।
ind=("${!array[@]}");eval eval echo "'\"\${array[ind[-'{1..${#array[@]}}']]}\"'"
যদিও আমি নতুন কিছু বলতে যাচ্ছি না এবং আমি tac
অ্যারেটি বিপরীত করতেও ব্যবহার করব , যদিও আমি বশ সংস্করণ ৪.৪ ব্যবহার করে বেলো সিঙ্গেল লাইন সমাধান উল্লেখ করার জন্য উদ্বেগজনক হবে:
$ read -d'\n' -a array < <(printf '%s\n' "${array[@]}" |tac)
পরীক্ষামূলক:
$ array=(1 2 3 4 5 6 10 11 12)
$ echo "${array[@]}"
1 2 3 4 5 6 10 11 12
$ read -d'\n' -a array < <(printf '%s\n' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
মনে রাখবেন যে পড়ার অভ্যন্তরে বর্ণের নামটি মূল অ্যারে হিসাবে নাম, তাই অস্থায়ী সঞ্চয়ের জন্য কোনও সাহায্যকারী অ্যারের প্রয়োজন হয় না।
আইএফএস সামঞ্জস্য করে বিকল্প বাস্তবায়ন:
$ IFS=$'\n' read -d '' -a array < <(printf '%s\n' "${array[@]}"|tac);declare -p array
declare -a array=([0]="12" [1]="11" [2]="10" [3]="6" [4]="5" [5]="4" [6]="3" [7]="2" [8]="1")
PS: আমি মনে করি উপরের সমাধানগুলি বিভিন্ন ব্যাশ বিল্টিন ফাংশন বাস্তবায়নের কারণে bash
বেলো সংস্করণে কাজ করবে না ।4.4
read
IFS
সংস্করণ কাজ করে কিন্তু এটি মুদ্রণ হয়: declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
। ব্যাশ ব্যবহার করা 4.4-5
। আপনি সরাতে পেয়েছিলাম ;declare -p array
প্রথম লাইন শেষে, তারপর এটি কাজ করে ...
declare -p
আসল অ্যারে (সূচি এবং বিষয়বস্তু) প্রিন্ট করার কেবলমাত্র দ্রুত উপায়। declare -p
আপনার আসল স্ক্রিপ্টে আপনার এই আদেশের দরকার নেই । যদি আপনার অ্যারে কার্যক্রমে কিছু ভুল হয়ে যায় তবে আপনি ${array[0]}="1 2 3 4 5 6 10 11 12"
একই ক্ষেত্রে শেষ করতে পারেন যে = একই সূচীতে সঞ্চিত সমস্ত মান - প্রতিধ্বনি ব্যবহার করে আপনি কোনও পার্থক্য দেখতে পাবেন না। দ্রুত অ্যারের প্রিন্টআউট ব্যবহার করে declare -p array
আপনাকে প্রতিটি সূচীতে প্রকৃত অ্যারে অভ্যাস এবং সংশ্লিষ্ট মানটি ফিরিয়ে দেবে।
read -d'\n'
কি আপনার পক্ষে কার্যকর হয়নি?
read -d'\n'
ঠিকভাবে কাজ করে.
একটি স্বেচ্ছাসেবী অ্যারে বিপরীত করতে (যে কোনও মান সহ কয়েকটি সংখ্যক উপাদান থাকতে পারে):
সাথে zsh
:
array_reversed=("${(@Oa)array}")
সঙ্গে bash
4.4+ দেওয়া যে bash
ভেরিয়েবল থাকতে পারে না NUL যাহাই হউক না কেন বাইট, আপনি গনুহ ব্যবহার করতে পারেন tac -s ''
মুদ্রিত যেমন NUL রেকর্ড সীমায়িত উপাদানে:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s\0' "${array[@]}" | tac -s '')
POSIXly, POSIX শেল অ্যারের বিপরীতে ( $@
, তৈরি $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code \"\${$n}\""
n=$((n - 1))
done
eval "$code"
খাঁটি বাশ সমাধান, ওয়ান-লাইনার হিসাবে কাজ করবে।
$: for (( i=${#array[@]}-1; i>=0; i-- ))
> do rev[${#rev[@]}]=${array[i]}
> done
$: echo "${rev[@]}"
7 6 5 4 3 2 1
rev+=( "${array[i]}" )
সহজ মনে হচ্ছে ।
আপনি ব্যবহার বিবেচনা করতে পারেন seq
array=(1 2 3 4 5 6 7)
for i in $(seq $((${#array[@]} - 1)) -1 0); do
echo ${array[$i]}
done
ফ্রিবিএসডি-তে আপনি -1 ইনক্রিমেন্ট প্যারামিটার বাদ দিতে পারেন:
for i in $(seq $((${#array[@]} - 1)) 0); do
echo ${array[$i]}
done
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
অথবা
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
7 6 5 4 3 2 1
$ tac --version
tac (GNU coreutils) 8.28
tac
ইতিমধ্যে উল্লিখিত ছিল: unix.stackexchange.com/a/412874/260978 , unix.stackexchange.com/a/467924/260978 , unix.stackexchange.com/a/413176/260978