how to randomly loop over an array (shuffle) in bash [duplicate]
This question already has an answer here:
Simple method to shuffle the elements of an array in BASH shell?
3 answers
Given an array of elements (servers), how do I shuffle the array to obtain a random new array ?
inarray=("serverA" "serverB" "serverC")
outarray=($(randomize_func $inarray[@])
echo $outarray[@]
serverB serverC serverA
There is a command shuf
(man page) but it does not exist on every linux.
This is my first attempt to post a self-answered question stackoverflow, if you have a better solution, please post it.
arrays bash random shuffle
marked as duplicate by tripleee
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 14 '18 at 5:09
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
|
show 1 more comment
This question already has an answer here:
Simple method to shuffle the elements of an array in BASH shell?
3 answers
Given an array of elements (servers), how do I shuffle the array to obtain a random new array ?
inarray=("serverA" "serverB" "serverC")
outarray=($(randomize_func $inarray[@])
echo $outarray[@]
serverB serverC serverA
There is a command shuf
(man page) but it does not exist on every linux.
This is my first attempt to post a self-answered question stackoverflow, if you have a better solution, please post it.
arrays bash random shuffle
marked as duplicate by tripleee
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 14 '18 at 5:09
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Neitherinarray
noroutarray
are actually arrays.
– chepner
Nov 9 '18 at 16:59
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43
|
show 1 more comment
This question already has an answer here:
Simple method to shuffle the elements of an array in BASH shell?
3 answers
Given an array of elements (servers), how do I shuffle the array to obtain a random new array ?
inarray=("serverA" "serverB" "serverC")
outarray=($(randomize_func $inarray[@])
echo $outarray[@]
serverB serverC serverA
There is a command shuf
(man page) but it does not exist on every linux.
This is my first attempt to post a self-answered question stackoverflow, if you have a better solution, please post it.
arrays bash random shuffle
This question already has an answer here:
Simple method to shuffle the elements of an array in BASH shell?
3 answers
Given an array of elements (servers), how do I shuffle the array to obtain a random new array ?
inarray=("serverA" "serverB" "serverC")
outarray=($(randomize_func $inarray[@])
echo $outarray[@]
serverB serverC serverA
There is a command shuf
(man page) but it does not exist on every linux.
This is my first attempt to post a self-answered question stackoverflow, if you have a better solution, please post it.
This question already has an answer here:
Simple method to shuffle the elements of an array in BASH shell?
3 answers
arrays bash random shuffle
arrays bash random shuffle
edited Nov 9 '18 at 17:06
JoKoT3
asked Nov 9 '18 at 16:11
JoKoT3JoKoT3
464
464
marked as duplicate by tripleee
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 14 '18 at 5:09
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by tripleee
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Nov 14 '18 at 5:09
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Neitherinarray
noroutarray
are actually arrays.
– chepner
Nov 9 '18 at 16:59
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43
|
show 1 more comment
Neitherinarray
noroutarray
are actually arrays.
– chepner
Nov 9 '18 at 16:59
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43
Neither
inarray
nor outarray
are actually arrays.– chepner
Nov 9 '18 at 16:59
Neither
inarray
nor outarray
are actually arrays.– chepner
Nov 9 '18 at 16:59
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43
|
show 1 more comment
4 Answers
4
active
oldest
votes
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=$outarray[idx]
outarray[idx]=$outarray[rand_idx]
outarray[rand_idx]=$tmp
fi
done
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "$inarray[@]"
# Display the contents of 'outarray'
declare -p outarray
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
add a comment |
This is the solution I found (it even works in bash < 4.0).
Shellchecked and edited thanks to comments below.
#!/bin/bash
# random permutation of input
perm()
# make the input an array
local -a items=( "$@" )
# all the indices of the array
local -a items_arr=( "$!items[@]" )
# create out array
local -a items_out=()
# loop while there is at least one index
while [ $#items_arr[@] -gt 0 ]; do
# pick a random number between 1 and the length of the indices array
local rand=$(( RANDOM % $#items_arr[@] ))
# get the item index from the array of indices
local items_idx=$items_arr[$rand]
# append that item to the out array
items_out+=("$items[$items_idx]")
### NOTE array is not reindexed when pop'ing, so we redo an array of
### index at each iteration
# pop the item
unset "items[$items_idx]"
# recreate the array
items_arr=( "$!items[@]" )
done
echo "$items_out[@]"
perm "server1" "server2" "server3" "server4" "server4" "server5" "server6" "server7" "server8"
It is more than possible that it can be optimized.
1
You should make all variableslocal
, or you leak them to global scope.
– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted$@
in items assignement, making so make you pass all arguments like this :"arg1" "arg2"...
instead on"arg1 arg2..."
. not sure what is best.
– JoKoT3
Nov 9 '18 at 17:38
1
Quoting is necessary if you want to shuffle an array like("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.
– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
|
show 2 more comments
The sort
utility has the ability to shuffle lists randomly.
Try this instead:
servers="serverA serverB serverC serverD"
for s in $servers ; do echo $s ; done | sort -R
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
add a comment |
You should use shuf
:
inarray=("serverA" "serverB" "serverC")
IFS=$'n' outarray=($(printf "%s$IFS" "$inarray[@]" | shuf))
Or when using array members with newlines and other strange characters, use null delimetered strings:
inarray=("serverA" "serverB" "serverC")
readarray -d '' outarray < <(printf "%s" "$inarray[@]" | shuf -z)
I recommendset -f
with the first one. And note you will needbash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simplewhile
read
combo for other versions :)
– PesaThe
Nov 9 '18 at 17:59
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=$outarray[idx]
outarray[idx]=$outarray[rand_idx]
outarray[rand_idx]=$tmp
fi
done
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "$inarray[@]"
# Display the contents of 'outarray'
declare -p outarray
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
add a comment |
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=$outarray[idx]
outarray[idx]=$outarray[rand_idx]
outarray[rand_idx]=$tmp
fi
done
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "$inarray[@]"
# Display the contents of 'outarray'
declare -p outarray
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
add a comment |
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=$outarray[idx]
outarray[idx]=$outarray[rand_idx]
outarray[rand_idx]=$tmp
fi
done
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "$inarray[@]"
# Display the contents of 'outarray'
declare -p outarray
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=$outarray[idx]
outarray[idx]=$outarray[rand_idx]
outarray[rand_idx]=$tmp
fi
done
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "$inarray[@]"
# Display the contents of 'outarray'
declare -p outarray
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
edited Nov 12 '18 at 18:31
answered Nov 9 '18 at 20:50
pjhpjh
1,669611
1,669611
add a comment |
add a comment |
This is the solution I found (it even works in bash < 4.0).
Shellchecked and edited thanks to comments below.
#!/bin/bash
# random permutation of input
perm()
# make the input an array
local -a items=( "$@" )
# all the indices of the array
local -a items_arr=( "$!items[@]" )
# create out array
local -a items_out=()
# loop while there is at least one index
while [ $#items_arr[@] -gt 0 ]; do
# pick a random number between 1 and the length of the indices array
local rand=$(( RANDOM % $#items_arr[@] ))
# get the item index from the array of indices
local items_idx=$items_arr[$rand]
# append that item to the out array
items_out+=("$items[$items_idx]")
### NOTE array is not reindexed when pop'ing, so we redo an array of
### index at each iteration
# pop the item
unset "items[$items_idx]"
# recreate the array
items_arr=( "$!items[@]" )
done
echo "$items_out[@]"
perm "server1" "server2" "server3" "server4" "server4" "server5" "server6" "server7" "server8"
It is more than possible that it can be optimized.
1
You should make all variableslocal
, or you leak them to global scope.
– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted$@
in items assignement, making so make you pass all arguments like this :"arg1" "arg2"...
instead on"arg1 arg2..."
. not sure what is best.
– JoKoT3
Nov 9 '18 at 17:38
1
Quoting is necessary if you want to shuffle an array like("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.
– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
|
show 2 more comments
This is the solution I found (it even works in bash < 4.0).
Shellchecked and edited thanks to comments below.
#!/bin/bash
# random permutation of input
perm()
# make the input an array
local -a items=( "$@" )
# all the indices of the array
local -a items_arr=( "$!items[@]" )
# create out array
local -a items_out=()
# loop while there is at least one index
while [ $#items_arr[@] -gt 0 ]; do
# pick a random number between 1 and the length of the indices array
local rand=$(( RANDOM % $#items_arr[@] ))
# get the item index from the array of indices
local items_idx=$items_arr[$rand]
# append that item to the out array
items_out+=("$items[$items_idx]")
### NOTE array is not reindexed when pop'ing, so we redo an array of
### index at each iteration
# pop the item
unset "items[$items_idx]"
# recreate the array
items_arr=( "$!items[@]" )
done
echo "$items_out[@]"
perm "server1" "server2" "server3" "server4" "server4" "server5" "server6" "server7" "server8"
It is more than possible that it can be optimized.
1
You should make all variableslocal
, or you leak them to global scope.
– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted$@
in items assignement, making so make you pass all arguments like this :"arg1" "arg2"...
instead on"arg1 arg2..."
. not sure what is best.
– JoKoT3
Nov 9 '18 at 17:38
1
Quoting is necessary if you want to shuffle an array like("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.
– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
|
show 2 more comments
This is the solution I found (it even works in bash < 4.0).
Shellchecked and edited thanks to comments below.
#!/bin/bash
# random permutation of input
perm()
# make the input an array
local -a items=( "$@" )
# all the indices of the array
local -a items_arr=( "$!items[@]" )
# create out array
local -a items_out=()
# loop while there is at least one index
while [ $#items_arr[@] -gt 0 ]; do
# pick a random number between 1 and the length of the indices array
local rand=$(( RANDOM % $#items_arr[@] ))
# get the item index from the array of indices
local items_idx=$items_arr[$rand]
# append that item to the out array
items_out+=("$items[$items_idx]")
### NOTE array is not reindexed when pop'ing, so we redo an array of
### index at each iteration
# pop the item
unset "items[$items_idx]"
# recreate the array
items_arr=( "$!items[@]" )
done
echo "$items_out[@]"
perm "server1" "server2" "server3" "server4" "server4" "server5" "server6" "server7" "server8"
It is more than possible that it can be optimized.
This is the solution I found (it even works in bash < 4.0).
Shellchecked and edited thanks to comments below.
#!/bin/bash
# random permutation of input
perm()
# make the input an array
local -a items=( "$@" )
# all the indices of the array
local -a items_arr=( "$!items[@]" )
# create out array
local -a items_out=()
# loop while there is at least one index
while [ $#items_arr[@] -gt 0 ]; do
# pick a random number between 1 and the length of the indices array
local rand=$(( RANDOM % $#items_arr[@] ))
# get the item index from the array of indices
local items_idx=$items_arr[$rand]
# append that item to the out array
items_out+=("$items[$items_idx]")
### NOTE array is not reindexed when pop'ing, so we redo an array of
### index at each iteration
# pop the item
unset "items[$items_idx]"
# recreate the array
items_arr=( "$!items[@]" )
done
echo "$items_out[@]"
perm "server1" "server2" "server3" "server4" "server4" "server5" "server6" "server7" "server8"
It is more than possible that it can be optimized.
edited Nov 13 '18 at 14:11
answered Nov 9 '18 at 16:25
JoKoT3JoKoT3
464
464
1
You should make all variableslocal
, or you leak them to global scope.
– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted$@
in items assignement, making so make you pass all arguments like this :"arg1" "arg2"...
instead on"arg1 arg2..."
. not sure what is best.
– JoKoT3
Nov 9 '18 at 17:38
1
Quoting is necessary if you want to shuffle an array like("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.
– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
|
show 2 more comments
1
You should make all variableslocal
, or you leak them to global scope.
– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted$@
in items assignement, making so make you pass all arguments like this :"arg1" "arg2"...
instead on"arg1 arg2..."
. not sure what is best.
– JoKoT3
Nov 9 '18 at 17:38
1
Quoting is necessary if you want to shuffle an array like("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.
– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
1
1
You should make all variables
local
, or you leak them to global scope.– Benjamin W.
Nov 9 '18 at 17:03
You should make all variables
local
, or you leak them to global scope.– Benjamin W.
Nov 9 '18 at 17:03
@chepner you quoted
$@
in items assignement, making so make you pass all arguments like this : "arg1" "arg2"...
instead on "arg1 arg2..."
. not sure what is best.– JoKoT3
Nov 9 '18 at 17:38
@chepner you quoted
$@
in items assignement, making so make you pass all arguments like this : "arg1" "arg2"...
instead on "arg1 arg2..."
. not sure what is best.– JoKoT3
Nov 9 '18 at 17:38
1
1
Quoting is necessary if you want to shuffle an array like
("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.– chepner
Nov 9 '18 at 17:41
Quoting is necessary if you want to shuffle an array like
("foo bar" "1 2 3")
. It preserves the whitespace in the elements without confusing it with the whitespace that separates the elements.– chepner
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@BenjaminW. thanks for you remark, variables localized
– JoKoT3
Nov 9 '18 at 17:41
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
@chepner great thanks !
– JoKoT3
Nov 9 '18 at 17:42
|
show 2 more comments
The sort
utility has the ability to shuffle lists randomly.
Try this instead:
servers="serverA serverB serverC serverD"
for s in $servers ; do echo $s ; done | sort -R
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
add a comment |
The sort
utility has the ability to shuffle lists randomly.
Try this instead:
servers="serverA serverB serverC serverD"
for s in $servers ; do echo $s ; done | sort -R
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
add a comment |
The sort
utility has the ability to shuffle lists randomly.
Try this instead:
servers="serverA serverB serverC serverD"
for s in $servers ; do echo $s ; done | sort -R
The sort
utility has the ability to shuffle lists randomly.
Try this instead:
servers="serverA serverB serverC serverD"
for s in $servers ; do echo $s ; done | sort -R
answered Nov 9 '18 at 16:35
squeamish ossifragesqueamish ossifrage
16.8k32361
16.8k32361
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
add a comment |
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
Thanks for your answer, my version of sort (GNU CoreUtils 5.97) does not have the -R option which was added in 2005 :O. Also, I use you answer to document that sort -R is not a true shuffle : being based on hash, it group together identical value (as documented in [bugs.debian.org/cgi-bin/bugreport.cgi?bug=641166]
– JoKoT3
Nov 9 '18 at 17:01
add a comment |
You should use shuf
:
inarray=("serverA" "serverB" "serverC")
IFS=$'n' outarray=($(printf "%s$IFS" "$inarray[@]" | shuf))
Or when using array members with newlines and other strange characters, use null delimetered strings:
inarray=("serverA" "serverB" "serverC")
readarray -d '' outarray < <(printf "%s" "$inarray[@]" | shuf -z)
I recommendset -f
with the first one. And note you will needbash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simplewhile
read
combo for other versions :)
– PesaThe
Nov 9 '18 at 17:59
add a comment |
You should use shuf
:
inarray=("serverA" "serverB" "serverC")
IFS=$'n' outarray=($(printf "%s$IFS" "$inarray[@]" | shuf))
Or when using array members with newlines and other strange characters, use null delimetered strings:
inarray=("serverA" "serverB" "serverC")
readarray -d '' outarray < <(printf "%s" "$inarray[@]" | shuf -z)
I recommendset -f
with the first one. And note you will needbash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simplewhile
read
combo for other versions :)
– PesaThe
Nov 9 '18 at 17:59
add a comment |
You should use shuf
:
inarray=("serverA" "serverB" "serverC")
IFS=$'n' outarray=($(printf "%s$IFS" "$inarray[@]" | shuf))
Or when using array members with newlines and other strange characters, use null delimetered strings:
inarray=("serverA" "serverB" "serverC")
readarray -d '' outarray < <(printf "%s" "$inarray[@]" | shuf -z)
You should use shuf
:
inarray=("serverA" "serverB" "serverC")
IFS=$'n' outarray=($(printf "%s$IFS" "$inarray[@]" | shuf))
Or when using array members with newlines and other strange characters, use null delimetered strings:
inarray=("serverA" "serverB" "serverC")
readarray -d '' outarray < <(printf "%s" "$inarray[@]" | shuf -z)
edited Nov 9 '18 at 17:57
answered Nov 9 '18 at 17:50
Kamil CukKamil Cuk
9,8071527
9,8071527
I recommendset -f
with the first one. And note you will needbash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simplewhile
read
combo for other versions :)
– PesaThe
Nov 9 '18 at 17:59
add a comment |
I recommendset -f
with the first one. And note you will needbash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simplewhile
read
combo for other versions :)
– PesaThe
Nov 9 '18 at 17:59
I recommend
set -f
with the first one. And note you will need bash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simple while
read
combo for other versions :)– PesaThe
Nov 9 '18 at 17:59
I recommend
set -f
with the first one. And note you will need bash
4.4 or later for the second one if I am not mistaken. You might also throw in a solution with a simple while
read
combo for other versions :)– PesaThe
Nov 9 '18 at 17:59
add a comment |
Neither
inarray
noroutarray
are actually arrays.– chepner
Nov 9 '18 at 16:59
And both assignments are syntactically invalid.
– Benjamin W.
Nov 9 '18 at 17:02
sorry, pseudocode, I edit my question
– JoKoT3
Nov 9 '18 at 17:05
I question the need to shuffle an array in a script that wouldn't be more appropriately written in another language.
– chepner
Nov 9 '18 at 17:18
trust me, real use case here :)
– JoKoT3
Nov 9 '18 at 17:43