picking a random line from stdout
I have a command which spouts a number 开发者_高级运维of lines to stdout:
$ listall
foo
bar
baz
How do I extract a random entry from this, in a one-liner (preferably without awk) so I can just use it in a pipe:
$ listall | pickrandom | sed ... | curl ...
Thanks!
listall | shuf | head -n 1
Some have complained about not having shuf
available on their installs, so maybe this is more accessible: listall | sort -R |head -n 1
.
-R
is "sort randomly".
you can do it with just bash, without other tools other than "listall"
$ lists=($(listall)) # put to array
$ num=${#lists[@]} # get number of items
$ rand=$((RANDOM%$num)) # generate random number
$ echo ${lists[$rand]}
Using Perl:
perl -MList::Util=shuffle -e'print((shuffle<>)[0])'
perl -e'print$listall[$key=int rand(@listall=<>)]'
This is memory-safe, unlike using shuf or List::Util shuffle:
listall | awk 'BEGIN { srand() } int(rand() * NR) == 0 { x = $0 } END { print x }'
It would only matter if listall could return a huge result.
For more information, see the DADS entry on reservoir sampling.
Save the following as a script (randomline.sh):
#! /bin/sh
set -- junk $(awk -v SEED=$$ 'BEGIN { srand(SEED) } { print rand(), $0 }' | sort -n | head -1)
shift 2
echo "$@"
and run it as
$ listall | randomline.sh
精彩评论