2010-02-27 12 views
9

tengo un comando que brota un número de líneas a stdout:recogiendo una línea azar de stdout

$ listall 
foo 
bar 
baz 

¿Cómo extraer una entrada al azar de esto, en una sola línea (preferiblemente sin awk) de modo Puedo usarlo en una tubería:

$ listall | pickrandom | sed ... | curl ... 

¡Gracias!

Respuesta

16
listall | shuf | head -n 1 
+0

Excelente, exactamente lo que necesitaba (no sabía sobre shuf) - ¡gracias! – AnC

+10

en realidad "listall | shuf -n 1" parece suficiente – xiechao

+1

No muy portátil: -bash: shuf: comando no encontrado – Idelic

2

Utilizando Perl:

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

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

+0

Gracias. Si bien es más complejo que simplemente usar shuf, podría ser útil en algún momento. – AnC

2

Ésta es la memoria de fallos, a diferencia de uso shuf o la lista de reproducción aleatoria :: Util:

listall | awk 'BEGIN { srand() } int(rand() * NR) == 0 { x = $0 } END { print x }'

Solo importaría si listall pudiera devolver un gran resultado.

Para obtener más información, consulte la entrada DADS en reservoir sampling.

+0

¡Es bueno saberlo, gracias! No es una preocupación para este caso en particular, pero ni siquiera había pensado en este tema antes ... – AnC

+1

Agregué un enlace con más información. :) –

2

puede hacerlo con sólo golpe, sin otras herramientas que no sean "listAll"

$ lists=($(listall)) # put to array 
$ num=${#lists[@]} # get number of items 
$ rand=$((RANDOM%$num)) # generate random number 
$ echo ${lists[$rand]} 
+0

¡Muchas respuestas excelentes aquí - gracias! – AnC

+0

Éste tiene que leer todas las líneas en la memoria – pihentagy

0

Guardar los siguientes como un guión (randomline.sh):

#! /bin/sh 
set -- junk $(awk -v SEED=$$ 'BEGIN { srand(SEED) } { print rand(), $0 }' | sort -n | head -1) 
shift 2 
echo "[email protected]" 

y ejecutarlo como

$ listall | randomline.sh
3

Algunos se quejaron de no tener shuf disponibles en sus instalaciones, así que tal vez ª es más accesible: listall | sort -R |head -n 1. -R es "ordenar aleatoriamente".

+1

Me temo que '-R' no está disponible en OS X. – AnC