जवाबों:
मैंने प्रश्न का लिखित रूप में उत्तर दिया है, और यह कोड सरणी को उलट देता है। (सरणी को उल्टा किए बिना तत्वों को रिवर्स ऑर्डर में प्रिंट करना 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 -n
4.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.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
चर में एनयूएल बाइट्स नहीं हो सकते हैं, आप 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