开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜