जवाबों:
मैंने प्रश्न का लिखित रूप में उत्तर दिया है, और यह कोड सरणी को उलट देता है। (सरणी को उल्टा किए बिना तत्वों को रिवर्स ऑर्डर में प्रिंट करना forअंतिम तत्व से शून्य तक गिना जाने वाला एक लूप है।) यह एक मानक "पहले और अंतिम" स्वैप है।
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[@]}"
आउटपुट:
६ ५ ४ ३ २ १ १
यदि 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 -n4.3 से पहले बैश संस्करणों में काम नहीं करता है।
जगह में सरणी पदों की अदला-बदली करने के लिए (यहां तक कि विरल सरणियों के साथ) (bash 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
2.03 के बाद से बैश के लिए:
#!/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
इसके अलावा (बिटवाइस निगेटिव ऑपरेटर का उपयोग करके) (4.2+ के बाद से):
#!/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सरणी को उलटने के लिए भी इस्तेमाल करूँगा , हालाँकि मैं bash संस्करण 4.4 का उपयोग करके bellow सिंगल लाइन सॉल्यूशन का उल्लेख करने के लिए चिंतित होऊंगा:
$ 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 को समायोजित करके वैकल्पिक कार्यान्वयन:
$ 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")
पुनश्च: मुझे लगता है कि अलग-अलग बैश बिलिन फ़ंक्शन कार्यान्वयन के कारण उपरोक्त समाधान bashबलो संस्करण में काम नहीं करेगा ।4.4read
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}")
bash4.4+ के साथ , यह देखते हुए कि bashचर में एनयूएल बाइट्स नहीं हो सकते हैं, आप tac -s ''एनयूएल सीमांकित के रूप में मुद्रित तत्वों पर GNU का उपयोग कर सकते हैं :
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[@]}
६ ५ ४ ३ २ १ १
$ 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