Bash - reverse an array
Is there a simple way to reverse an array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
so I would get: 7 6 5 4 3 2 1
instead of: 1 2 3 4 5 6 7
bash shell-script array bash-array
add a comment |
Is there a simple way to reverse an array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
so I would get: 7 6 5 4 3 2 1
instead of: 1 2 3 4 5 6 7
bash shell-script array bash-array
add a comment |
Is there a simple way to reverse an array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
so I would get: 7 6 5 4 3 2 1
instead of: 1 2 3 4 5 6 7
bash shell-script array bash-array
Is there a simple way to reverse an array?
#!/bin/bash
array=(1 2 3 4 5 6 7)
echo "${array[@]}"
so I would get: 7 6 5 4 3 2 1
instead of: 1 2 3 4 5 6 7
bash shell-script array bash-array
bash shell-script array bash-array
edited Dec 25 '17 at 1:55
jimmij
31.2k871106
31.2k871106
asked Dec 25 '17 at 0:53
nathnath
945625
945625
add a comment |
add a comment |
9 Answers
9
active
oldest
votes
I have answered the question as written, and this code reverses the array. (Printing the elements in reverse order without reversing the array is just a for
loop counting down from the last element to zero.) This is a standard "swap first and last" algorithm.
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[@]}"
It works for arrays of odd and even length.
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
add a comment |
Another unconventional approach:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
Output:
7 6 5 4 3 2 1
If extdebug
is enabled, array BASH_ARGV
contains in a function all positional parameters in reverse order.
add a comment |
Unconventional approach (all not pure bash
):
if all elements in an array are just one characters (like in the question) you can use
rev
:
echo "${array[@]}" | rev
otherwise:
printf '%sn' "${array[@]}" | tac | tr 'n' ' '; echo
and if you can use
zsh
:
echo ${(Oa)array}
just been looking uptac
, as the opposite ofcat
quite good to remember, THANKS!
– nath
Dec 25 '17 at 2:17
1
Though i like the idea ofrev
, i need to mention thatrev
will not work correctly for numbers with two digits. For example an array element of12
using rev will be printed as21
. Give it a try ;-)
– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
add a comment |
If you actually want the reverse in another array:
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
}
Then:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
Gives:
4 3 2 1
This should correctly handle cases where an array index is missing, say you had array=([1]=1 [2]=2 [4]=4)
, in which case looping from 0 to the highest index may add additional, empty, elements.
Thanks for this one, it works pretty well, though for some reasonshellcheck
prints two warnings:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
@nath they're indirectly used, that's what thedeclare
line is for.
– muru
Dec 27 '17 at 0:37
Clever, but note thatdeclare -n
seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:33
add a comment |
To swap the array positions in place (even with sparse arrays)(since bash 3.0):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=1 [6]=2 [10]=3 [11]=4 [20]=5 [21]=6 [40]=7)
declare -p array
scan=("${!array[@]}") # non-sparse array of indexes.
min=0; max=$(( ${#scan[@]} - 1 )) # for all (indexed) elements.
while [[ min -lt max ]]
do
x="${array[scan[min]]}" # temp variable
array[scan[min]]="${array[scan[max]]}" # Exchange first and last
array[scan[max]]="$x" #
(( min++, max-- )) # Move closer
done
declare -p array
echo "Final Array swapped in-place"
echo "${array[@]}"
On execution:
./script
declare -a array=([5]="1" [6]="2" [10]="3" [11]="4" [20]="5" [21]="6" [40]="7")
declare -a array=([5]="7" [6]="6" [10]="5" [11]="4" [20]="3" [21]="2" [40]="1")
Final Array swapped in place
7 6 5 4 3 2 1
For older bash, you need to use a loop (in bash (since 2.04)) and using $a
to avoid the trailing space:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s ' "$a" "${array[i]}"
a=" "
done
echo
For bash since 2.03:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
Also (using the negate operator) (since bash 4.2+):
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
add a comment |
Ugly, unmaintainable, but one-liner:
eval eval echo "'"${array['{$((${#array[@]}-1))..0}']}"'"
add a comment |
Though i am not going to tell something new and i will also use tac
to reverse the array, i though that would be worthing to mention bellow single line solution using bash version 4.4:
$ read -d'n' -a array < <(printf '%sn' "${array[@]}" |tac)
Testing:
$ 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 '%sn' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
Mind that the var name inside read is the name as the original array, so no helper array is required for temp storage.
Alternative implementation by adjusting IFS :
$ IFS=$'n' read -d '' -a array < <(printf '%sn' "${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: I think above solutions will not work in bash
bellow version 4.4
due to different read
bash builtin function implementation.
TheIFS
version works but it is also printing:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash4.4-5
. You got to remove;declare -p array
at the end of the first line, then it works...
– nath
Dec 26 '17 at 22:59
1
@nathdeclare -p
is just a quick way to make bash print the real array (index and contents). You don't need thisdeclare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout usingdeclare -p array
will return you the real array indeces and the corresponding value in each index.
– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, theread -d'n'
method did not work for you?
– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.
– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
|
show 1 more comment
To reverse an arbitrary array (which may contain any number of elements with any values):
With zsh
:
array_reversed=("${(@Oa)array}")
With bash
4.4+, given that bash
variables can't contain NUL bytes anyway, you can use GNU tac -s ''
on the elements printed as NUL delimited records:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s' "${array[@]}" | tac -s '')
POSIXly, to reverse the POSIX shell array ($@
, made of $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code "${$n}""
n=$((n - 1))
done
eval "$code"
add a comment |
Bash
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
Or
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
Result
7 6 5 4 3 2 1
Version
$ tac --version
tac (GNU coreutils) 8.28
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f412868%2fbash-reverse-an-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
I have answered the question as written, and this code reverses the array. (Printing the elements in reverse order without reversing the array is just a for
loop counting down from the last element to zero.) This is a standard "swap first and last" algorithm.
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[@]}"
It works for arrays of odd and even length.
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
add a comment |
I have answered the question as written, and this code reverses the array. (Printing the elements in reverse order without reversing the array is just a for
loop counting down from the last element to zero.) This is a standard "swap first and last" algorithm.
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[@]}"
It works for arrays of odd and even length.
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
add a comment |
I have answered the question as written, and this code reverses the array. (Printing the elements in reverse order without reversing the array is just a for
loop counting down from the last element to zero.) This is a standard "swap first and last" algorithm.
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[@]}"
It works for arrays of odd and even length.
I have answered the question as written, and this code reverses the array. (Printing the elements in reverse order without reversing the array is just a for
loop counting down from the last element to zero.) This is a standard "swap first and last" algorithm.
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[@]}"
It works for arrays of odd and even length.
edited Dec 25 '17 at 2:17
answered Dec 25 '17 at 1:07
roaimaroaima
44.1k555119
44.1k555119
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
add a comment |
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
Please make a note that this doesn't work for sparse arrays.
– Isaac
Dec 25 '17 at 20:38
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
@Isaac there's a solution on StackOverflow if you need to handle those.
– roaima
Dec 25 '17 at 22:45
Solved here.
– Isaac
Sep 10 '18 at 5:05
Solved here.
– Isaac
Sep 10 '18 at 5:05
add a comment |
Another unconventional approach:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
Output:
7 6 5 4 3 2 1
If extdebug
is enabled, array BASH_ARGV
contains in a function all positional parameters in reverse order.
add a comment |
Another unconventional approach:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
Output:
7 6 5 4 3 2 1
If extdebug
is enabled, array BASH_ARGV
contains in a function all positional parameters in reverse order.
add a comment |
Another unconventional approach:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
Output:
7 6 5 4 3 2 1
If extdebug
is enabled, array BASH_ARGV
contains in a function all positional parameters in reverse order.
Another unconventional approach:
#!/bin/bash
array=(1 2 3 4 5 6 7)
f() { array=("${BASH_ARGV[@]}"); }
shopt -s extdebug
f "${array[@]}"
shopt -u extdebug
echo "${array[@]}"
Output:
7 6 5 4 3 2 1
If extdebug
is enabled, array BASH_ARGV
contains in a function all positional parameters in reverse order.
edited Dec 25 '17 at 15:50
answered Dec 25 '17 at 5:52
CyrusCyrus
7,3112837
7,3112837
add a comment |
add a comment |
Unconventional approach (all not pure bash
):
if all elements in an array are just one characters (like in the question) you can use
rev
:
echo "${array[@]}" | rev
otherwise:
printf '%sn' "${array[@]}" | tac | tr 'n' ' '; echo
and if you can use
zsh
:
echo ${(Oa)array}
just been looking uptac
, as the opposite ofcat
quite good to remember, THANKS!
– nath
Dec 25 '17 at 2:17
1
Though i like the idea ofrev
, i need to mention thatrev
will not work correctly for numbers with two digits. For example an array element of12
using rev will be printed as21
. Give it a try ;-)
– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
add a comment |
Unconventional approach (all not pure bash
):
if all elements in an array are just one characters (like in the question) you can use
rev
:
echo "${array[@]}" | rev
otherwise:
printf '%sn' "${array[@]}" | tac | tr 'n' ' '; echo
and if you can use
zsh
:
echo ${(Oa)array}
just been looking uptac
, as the opposite ofcat
quite good to remember, THANKS!
– nath
Dec 25 '17 at 2:17
1
Though i like the idea ofrev
, i need to mention thatrev
will not work correctly for numbers with two digits. For example an array element of12
using rev will be printed as21
. Give it a try ;-)
– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
add a comment |
Unconventional approach (all not pure bash
):
if all elements in an array are just one characters (like in the question) you can use
rev
:
echo "${array[@]}" | rev
otherwise:
printf '%sn' "${array[@]}" | tac | tr 'n' ' '; echo
and if you can use
zsh
:
echo ${(Oa)array}
Unconventional approach (all not pure bash
):
if all elements in an array are just one characters (like in the question) you can use
rev
:
echo "${array[@]}" | rev
otherwise:
printf '%sn' "${array[@]}" | tac | tr 'n' ' '; echo
and if you can use
zsh
:
echo ${(Oa)array}
answered Dec 25 '17 at 1:52
jimmijjimmij
31.2k871106
31.2k871106
just been looking uptac
, as the opposite ofcat
quite good to remember, THANKS!
– nath
Dec 25 '17 at 2:17
1
Though i like the idea ofrev
, i need to mention thatrev
will not work correctly for numbers with two digits. For example an array element of12
using rev will be printed as21
. Give it a try ;-)
– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
add a comment |
just been looking uptac
, as the opposite ofcat
quite good to remember, THANKS!
– nath
Dec 25 '17 at 2:17
1
Though i like the idea ofrev
, i need to mention thatrev
will not work correctly for numbers with two digits. For example an array element of12
using rev will be printed as21
. Give it a try ;-)
– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
just been looking up
tac
, as the opposite of cat
quite good to remember, THANKS!– nath
Dec 25 '17 at 2:17
just been looking up
tac
, as the opposite of cat
quite good to remember, THANKS!– nath
Dec 25 '17 at 2:17
1
1
Though i like the idea of
rev
, i need to mention that rev
will not work correctly for numbers with two digits. For example an array element of 12
using rev will be printed as 21
. Give it a try ;-)– George Vasiliou
Dec 26 '17 at 21:46
Though i like the idea of
rev
, i need to mention that rev
will not work correctly for numbers with two digits. For example an array element of 12
using rev will be printed as 21
. Give it a try ;-)– George Vasiliou
Dec 26 '17 at 21:46
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
@GeorgeVasiliou Yes, that will work only if all elements are one characters (numbers, letters, punctations, ...). That's why I gave also second, more general solution.
– jimmij
Dec 26 '17 at 22:04
add a comment |
If you actually want the reverse in another array:
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
}
Then:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
Gives:
4 3 2 1
This should correctly handle cases where an array index is missing, say you had array=([1]=1 [2]=2 [4]=4)
, in which case looping from 0 to the highest index may add additional, empty, elements.
Thanks for this one, it works pretty well, though for some reasonshellcheck
prints two warnings:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
@nath they're indirectly used, that's what thedeclare
line is for.
– muru
Dec 27 '17 at 0:37
Clever, but note thatdeclare -n
seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:33
add a comment |
If you actually want the reverse in another array:
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
}
Then:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
Gives:
4 3 2 1
This should correctly handle cases where an array index is missing, say you had array=([1]=1 [2]=2 [4]=4)
, in which case looping from 0 to the highest index may add additional, empty, elements.
Thanks for this one, it works pretty well, though for some reasonshellcheck
prints two warnings:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
@nath they're indirectly used, that's what thedeclare
line is for.
– muru
Dec 27 '17 at 0:37
Clever, but note thatdeclare -n
seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:33
add a comment |
If you actually want the reverse in another array:
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
}
Then:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
Gives:
4 3 2 1
This should correctly handle cases where an array index is missing, say you had array=([1]=1 [2]=2 [4]=4)
, in which case looping from 0 to the highest index may add additional, empty, elements.
If you actually want the reverse in another array:
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
}
Then:
array=(1 2 3 4)
reverse array foo
echo "${foo[@]}"
Gives:
4 3 2 1
This should correctly handle cases where an array index is missing, say you had array=([1]=1 [2]=2 [4]=4)
, in which case looping from 0 to the highest index may add additional, empty, elements.
answered Dec 25 '17 at 9:20
murumuru
1
1
Thanks for this one, it works pretty well, though for some reasonshellcheck
prints two warnings:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
@nath they're indirectly used, that's what thedeclare
line is for.
– muru
Dec 27 '17 at 0:37
Clever, but note thatdeclare -n
seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:33
add a comment |
Thanks for this one, it works pretty well, though for some reasonshellcheck
prints two warnings:array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for:echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
@nath they're indirectly used, that's what thedeclare
line is for.
– muru
Dec 27 '17 at 0:37
Clever, but note thatdeclare -n
seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:33
Thanks for this one, it works pretty well, though for some reason
shellcheck
prints two warnings: array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for: echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
Thanks for this one, it works pretty well, though for some reason
shellcheck
prints two warnings: array=(1 2 3 4)
<-- SC2034: array appears unused. Verify it or export it.
and for: echo "${foo[@]}"
<-- SC2154: foo is referenced but not assigned.
– nath
Dec 26 '17 at 23:15
1
1
@nath they're indirectly used, that's what the
declare
line is for.– muru
Dec 27 '17 at 0:37
@nath they're indirectly used, that's what the
declare
line is for.– muru
Dec 27 '17 at 0:37
Clever, but note that
declare -n
seems not to work in bash versions before 4.3.– G-Man
Sep 9 '18 at 21:33
Clever, but note that
declare -n
seems not to work in bash versions before 4.3.– G-Man
Sep 9 '18 at 21:33
add a comment |
To swap the array positions in place (even with sparse arrays)(since bash 3.0):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=1 [6]=2 [10]=3 [11]=4 [20]=5 [21]=6 [40]=7)
declare -p array
scan=("${!array[@]}") # non-sparse array of indexes.
min=0; max=$(( ${#scan[@]} - 1 )) # for all (indexed) elements.
while [[ min -lt max ]]
do
x="${array[scan[min]]}" # temp variable
array[scan[min]]="${array[scan[max]]}" # Exchange first and last
array[scan[max]]="$x" #
(( min++, max-- )) # Move closer
done
declare -p array
echo "Final Array swapped in-place"
echo "${array[@]}"
On execution:
./script
declare -a array=([5]="1" [6]="2" [10]="3" [11]="4" [20]="5" [21]="6" [40]="7")
declare -a array=([5]="7" [6]="6" [10]="5" [11]="4" [20]="3" [21]="2" [40]="1")
Final Array swapped in place
7 6 5 4 3 2 1
For older bash, you need to use a loop (in bash (since 2.04)) and using $a
to avoid the trailing space:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s ' "$a" "${array[i]}"
a=" "
done
echo
For bash since 2.03:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
Also (using the negate operator) (since bash 4.2+):
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
add a comment |
To swap the array positions in place (even with sparse arrays)(since bash 3.0):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=1 [6]=2 [10]=3 [11]=4 [20]=5 [21]=6 [40]=7)
declare -p array
scan=("${!array[@]}") # non-sparse array of indexes.
min=0; max=$(( ${#scan[@]} - 1 )) # for all (indexed) elements.
while [[ min -lt max ]]
do
x="${array[scan[min]]}" # temp variable
array[scan[min]]="${array[scan[max]]}" # Exchange first and last
array[scan[max]]="$x" #
(( min++, max-- )) # Move closer
done
declare -p array
echo "Final Array swapped in-place"
echo "${array[@]}"
On execution:
./script
declare -a array=([5]="1" [6]="2" [10]="3" [11]="4" [20]="5" [21]="6" [40]="7")
declare -a array=([5]="7" [6]="6" [10]="5" [11]="4" [20]="3" [21]="2" [40]="1")
Final Array swapped in place
7 6 5 4 3 2 1
For older bash, you need to use a loop (in bash (since 2.04)) and using $a
to avoid the trailing space:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s ' "$a" "${array[i]}"
a=" "
done
echo
For bash since 2.03:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
Also (using the negate operator) (since bash 4.2+):
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
add a comment |
To swap the array positions in place (even with sparse arrays)(since bash 3.0):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=1 [6]=2 [10]=3 [11]=4 [20]=5 [21]=6 [40]=7)
declare -p array
scan=("${!array[@]}") # non-sparse array of indexes.
min=0; max=$(( ${#scan[@]} - 1 )) # for all (indexed) elements.
while [[ min -lt max ]]
do
x="${array[scan[min]]}" # temp variable
array[scan[min]]="${array[scan[max]]}" # Exchange first and last
array[scan[max]]="$x" #
(( min++, max-- )) # Move closer
done
declare -p array
echo "Final Array swapped in-place"
echo "${array[@]}"
On execution:
./script
declare -a array=([5]="1" [6]="2" [10]="3" [11]="4" [20]="5" [21]="6" [40]="7")
declare -a array=([5]="7" [6]="6" [10]="5" [11]="4" [20]="3" [21]="2" [40]="1")
Final Array swapped in place
7 6 5 4 3 2 1
For older bash, you need to use a loop (in bash (since 2.04)) and using $a
to avoid the trailing space:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s ' "$a" "${array[i]}"
a=" "
done
echo
For bash since 2.03:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
Also (using the negate operator) (since bash 4.2+):
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
To swap the array positions in place (even with sparse arrays)(since bash 3.0):
#!/bin/bash
# Declare an sparse array to test:
array=([5]=1 [6]=2 [10]=3 [11]=4 [20]=5 [21]=6 [40]=7)
declare -p array
scan=("${!array[@]}") # non-sparse array of indexes.
min=0; max=$(( ${#scan[@]} - 1 )) # for all (indexed) elements.
while [[ min -lt max ]]
do
x="${array[scan[min]]}" # temp variable
array[scan[min]]="${array[scan[max]]}" # Exchange first and last
array[scan[max]]="$x" #
(( min++, max-- )) # Move closer
done
declare -p array
echo "Final Array swapped in-place"
echo "${array[@]}"
On execution:
./script
declare -a array=([5]="1" [6]="2" [10]="3" [11]="4" [20]="5" [21]="6" [40]="7")
declare -a array=([5]="7" [6]="6" [10]="5" [11]="4" [20]="3" [21]="2" [40]="1")
Final Array swapped in place
7 6 5 4 3 2 1
For older bash, you need to use a loop (in bash (since 2.04)) and using $a
to avoid the trailing space:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=last-1 ; i>=0 ; i-- ));do
printf '%s%s ' "$a" "${array[i]}"
a=" "
done
echo
For bash since 2.03:
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a="";i=0
while [[ last -ge $((i+=1)) ]]; do
printf '%s%s' "$a" "${array[ last-i ]}"
a=" "
done
echo
Also (using the negate operator) (since bash 4.2+):
#!/bin/bash
array=(1 2 3 4 5 6 7)
last=${#array[@]}
a=""
for (( i=0 ; i<last ; i++ )); do
printf '%s%s' "$a" "${array[~i]}"
a=" "
done
echo
edited Sep 10 '18 at 5:03
answered Dec 25 '17 at 1:12
IsaacIsaac
11.8k11752
11.8k11752
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
add a comment |
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Addressing an array’s elements from the end backwards with negative subscripts seems not to work in bash versions before 4.3.
– G-Man
Sep 9 '18 at 21:14
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
Actually, addressing negative numbers was changed in 4.2-alpha. And the script with negated values works from that version. @G-Man p. Negative subscripts to indexed arrays, now treated as offsets from the maximum assigned index + 1. but Bash-hackers reports incorrectly 4.1 numerically indexed arrays can be accessed from the end using negative indexes
– Isaac
Sep 10 '18 at 4:31
add a comment |
Ugly, unmaintainable, but one-liner:
eval eval echo "'"${array['{$((${#array[@]}-1))..0}']}"'"
add a comment |
Ugly, unmaintainable, but one-liner:
eval eval echo "'"${array['{$((${#array[@]}-1))..0}']}"'"
add a comment |
Ugly, unmaintainable, but one-liner:
eval eval echo "'"${array['{$((${#array[@]}-1))..0}']}"'"
Ugly, unmaintainable, but one-liner:
eval eval echo "'"${array['{$((${#array[@]}-1))..0}']}"'"
answered Dec 27 '17 at 16:09
user23013user23013
627412
627412
add a comment |
add a comment |
Though i am not going to tell something new and i will also use tac
to reverse the array, i though that would be worthing to mention bellow single line solution using bash version 4.4:
$ read -d'n' -a array < <(printf '%sn' "${array[@]}" |tac)
Testing:
$ 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 '%sn' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
Mind that the var name inside read is the name as the original array, so no helper array is required for temp storage.
Alternative implementation by adjusting IFS :
$ IFS=$'n' read -d '' -a array < <(printf '%sn' "${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: I think above solutions will not work in bash
bellow version 4.4
due to different read
bash builtin function implementation.
TheIFS
version works but it is also printing:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash4.4-5
. You got to remove;declare -p array
at the end of the first line, then it works...
– nath
Dec 26 '17 at 22:59
1
@nathdeclare -p
is just a quick way to make bash print the real array (index and contents). You don't need thisdeclare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout usingdeclare -p array
will return you the real array indeces and the corresponding value in each index.
– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, theread -d'n'
method did not work for you?
– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.
– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
|
show 1 more comment
Though i am not going to tell something new and i will also use tac
to reverse the array, i though that would be worthing to mention bellow single line solution using bash version 4.4:
$ read -d'n' -a array < <(printf '%sn' "${array[@]}" |tac)
Testing:
$ 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 '%sn' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
Mind that the var name inside read is the name as the original array, so no helper array is required for temp storage.
Alternative implementation by adjusting IFS :
$ IFS=$'n' read -d '' -a array < <(printf '%sn' "${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: I think above solutions will not work in bash
bellow version 4.4
due to different read
bash builtin function implementation.
TheIFS
version works but it is also printing:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash4.4-5
. You got to remove;declare -p array
at the end of the first line, then it works...
– nath
Dec 26 '17 at 22:59
1
@nathdeclare -p
is just a quick way to make bash print the real array (index and contents). You don't need thisdeclare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout usingdeclare -p array
will return you the real array indeces and the corresponding value in each index.
– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, theread -d'n'
method did not work for you?
– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.
– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
|
show 1 more comment
Though i am not going to tell something new and i will also use tac
to reverse the array, i though that would be worthing to mention bellow single line solution using bash version 4.4:
$ read -d'n' -a array < <(printf '%sn' "${array[@]}" |tac)
Testing:
$ 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 '%sn' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
Mind that the var name inside read is the name as the original array, so no helper array is required for temp storage.
Alternative implementation by adjusting IFS :
$ IFS=$'n' read -d '' -a array < <(printf '%sn' "${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: I think above solutions will not work in bash
bellow version 4.4
due to different read
bash builtin function implementation.
Though i am not going to tell something new and i will also use tac
to reverse the array, i though that would be worthing to mention bellow single line solution using bash version 4.4:
$ read -d'n' -a array < <(printf '%sn' "${array[@]}" |tac)
Testing:
$ 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 '%sn' "${array[@]}"|tac)
$ echo "${array[@]}"
12 11 10 6 5 4 3 2 1
Mind that the var name inside read is the name as the original array, so no helper array is required for temp storage.
Alternative implementation by adjusting IFS :
$ IFS=$'n' read -d '' -a array < <(printf '%sn' "${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: I think above solutions will not work in bash
bellow version 4.4
due to different read
bash builtin function implementation.
edited Dec 26 '17 at 22:24
answered Dec 26 '17 at 22:14
George VasiliouGeorge Vasiliou
5,66031028
5,66031028
TheIFS
version works but it is also printing:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash4.4-5
. You got to remove;declare -p array
at the end of the first line, then it works...
– nath
Dec 26 '17 at 22:59
1
@nathdeclare -p
is just a quick way to make bash print the real array (index and contents). You don't need thisdeclare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout usingdeclare -p array
will return you the real array indeces and the corresponding value in each index.
– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, theread -d'n'
method did not work for you?
– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.
– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
|
show 1 more comment
TheIFS
version works but it is also printing:declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash4.4-5
. You got to remove;declare -p array
at the end of the first line, then it works...
– nath
Dec 26 '17 at 22:59
1
@nathdeclare -p
is just a quick way to make bash print the real array (index and contents). You don't need thisdeclare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout usingdeclare -p array
will return you the real array indeces and the corresponding value in each index.
– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, theread -d'n'
method did not work for you?
– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.
– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
The
IFS
version works but it is also printing: declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash 4.4-5
. You got to remove ;declare -p array
at the end of the first line, then it works...– nath
Dec 26 '17 at 22:59
The
IFS
version works but it is also printing: declare -a array=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="10" [7]="11" [8]="12")
. Using bash 4.4-5
. You got to remove ;declare -p array
at the end of the first line, then it works...– nath
Dec 26 '17 at 22:59
1
1
@nath
declare -p
is just a quick way to make bash print the real array (index and contents). You don't need this declare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that ${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout using declare -p array
will return you the real array indeces and the corresponding value in each index.– George Vasiliou
Dec 26 '17 at 23:17
@nath
declare -p
is just a quick way to make bash print the real array (index and contents). You don't need this declare -p
command in your real script. If something goes wrong in your arrays assignments you could end up in a case that ${array[0]}="1 2 3 4 5 6 10 11 12"
= all values stored in the same index - using echo you will see no difference. For a quick array printout using declare -p array
will return you the real array indeces and the corresponding value in each index.– George Vasiliou
Dec 26 '17 at 23:17
@nath By the way, the
read -d'n'
method did not work for you?– George Vasiliou
Dec 26 '17 at 23:18
@nath By the way, the
read -d'n'
method did not work for you?– George Vasiliou
Dec 26 '17 at 23:18
read -d'n'
works fine.– nath
Dec 26 '17 at 23:23
read -d'n'
works fine.– nath
Dec 26 '17 at 23:23
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
ahhh got you! SORRY :-)
– nath
Dec 26 '17 at 23:25
|
show 1 more comment
To reverse an arbitrary array (which may contain any number of elements with any values):
With zsh
:
array_reversed=("${(@Oa)array}")
With bash
4.4+, given that bash
variables can't contain NUL bytes anyway, you can use GNU tac -s ''
on the elements printed as NUL delimited records:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s' "${array[@]}" | tac -s '')
POSIXly, to reverse the POSIX shell array ($@
, made of $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code "${$n}""
n=$((n - 1))
done
eval "$code"
add a comment |
To reverse an arbitrary array (which may contain any number of elements with any values):
With zsh
:
array_reversed=("${(@Oa)array}")
With bash
4.4+, given that bash
variables can't contain NUL bytes anyway, you can use GNU tac -s ''
on the elements printed as NUL delimited records:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s' "${array[@]}" | tac -s '')
POSIXly, to reverse the POSIX shell array ($@
, made of $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code "${$n}""
n=$((n - 1))
done
eval "$code"
add a comment |
To reverse an arbitrary array (which may contain any number of elements with any values):
With zsh
:
array_reversed=("${(@Oa)array}")
With bash
4.4+, given that bash
variables can't contain NUL bytes anyway, you can use GNU tac -s ''
on the elements printed as NUL delimited records:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s' "${array[@]}" | tac -s '')
POSIXly, to reverse the POSIX shell array ($@
, made of $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code "${$n}""
n=$((n - 1))
done
eval "$code"
To reverse an arbitrary array (which may contain any number of elements with any values):
With zsh
:
array_reversed=("${(@Oa)array}")
With bash
4.4+, given that bash
variables can't contain NUL bytes anyway, you can use GNU tac -s ''
on the elements printed as NUL delimited records:
readarray -td '' array_reversed < <(
((${#array[@]})) && printf '%s' "${array[@]}" | tac -s '')
POSIXly, to reverse the POSIX shell array ($@
, made of $1
, $2
...):
code='set --'
n=$#
while [ "$n" -gt 0 ]; do
code="$code "${$n}""
n=$((n - 1))
done
eval "$code"
answered Sep 9 '18 at 20:40
Stéphane ChazelasStéphane Chazelas
303k56570926
303k56570926
add a comment |
add a comment |
Bash
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
Or
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
Result
7 6 5 4 3 2 1
Version
$ tac --version
tac (GNU coreutils) 8.28
add a comment |
Bash
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
Or
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
Result
7 6 5 4 3 2 1
Version
$ tac --version
tac (GNU coreutils) 8.28
add a comment |
Bash
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
Or
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
Result
7 6 5 4 3 2 1
Version
$ tac --version
tac (GNU coreutils) 8.28
Bash
array=(1 2 3 4 5 6 7)
echo "${array[@]} " | tac -s ' '
Or
array=(1 2 3 4 5 6 7)
reverse=$(echo "${array[@]} " | tac -s ' ')
echo ${reverse[@]}
Result
7 6 5 4 3 2 1
Version
$ tac --version
tac (GNU coreutils) 8.28
answered 21 mins ago
monmon
1235
1235
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f412868%2fbash-reverse-an-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown