Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

picking a random line from stdout

Tags:

bash

random

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!

like image 220
AnC Avatar asked Feb 27 '10 08:02

AnC


5 Answers

listall | shuf | head -n 1
like image 112
xiechao Avatar answered Oct 05 '22 22:10

xiechao


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]}
like image 20
ghostdog74 Avatar answered Oct 05 '22 22:10

ghostdog74


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".

like image 24
appas Avatar answered Oct 06 '22 00:10

appas


Using Perl:

  • perl -MList::Util=shuffle -e'print((shuffle<>)[0])'

  • perl -e'print$listall[$key=int rand(@listall=<>)]'

like image 35
Alan Haggai Alavi Avatar answered Oct 05 '22 22:10

Alan Haggai Alavi


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.

like image 31
Steven Huwig Avatar answered Oct 06 '22 00:10

Steven Huwig