¿Cómo puedo cambiar aleatoriamente las líneas en un archivo utilizando herramientas estándar de Red Hat Linux?

StackOverflow https://stackoverflow.com/questions/886237

Pregunta

¿Cómo puedo cambiar aleatoriamente las líneas en un archivo utilizando herramientas estándar en Red Hat Linux?

No tengo el comando shuf, por lo que estoy buscando algo como un perl o awk de una sola línea que realiza la misma tarea.

¿Fue útil?

Solución

Y un Perl de una sola línea que hay!

perl -MList::Util -e 'print List::Util::shuffle <>'

Se utiliza un módulo, pero el módulo es parte de la distribución de código Perl. Si eso no es lo suficientemente bueno, puede considerar rodar su propia cuenta.

He intentado utilizar esto con la bandera -i ( "edición en el lugar") que tiene que editar el archivo. La documentación sugiere que debería funcionar, pero no es así. Todavía muestra el archivo arrastrando los pies a la salida estándar, pero esta vez se elimina el original. Le sugiero que no lo usa.

Considere una secuencia de comandos shell:

#!/bin/sh

if [[ $# -eq 0 ]]
then
  echo "Usage: $0 [file ...]"
  exit 1
fi

for i in "$@"
do
  perl -MList::Util -e 'print List::Util::shuffle <>' $i > $i.new
  if [[ `wc -c $i` -eq `wc -c $i.new` ]]
  then
    mv $i.new $i
  else
    echo "Error for file $i!"
  fi
done

No probado, pero es de esperar que funciona.

Otros consejos

Um, no olvidemos

sort --random-sort

shuf es la mejor manera.

sort -R es muy lento. Sólo traté de ordenar el archivo de 5GB. Me di por vencido después de 2,5 horas. Entonces shuf ordenadas en un minuto.

cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-

Leer el archivo, anteponga cada línea con un número aleatorio, ordenar el archivo en esos prefijos al azar, cortar los prefijos después. De una sola línea que debe trabajar en cualquier semi-moderno shell.

EDIT:. Incorpora las declaraciones de Richard Hansen

A de una sola línea para el pitón:

python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile

Y para la impresión de una única línea aleatoria:

python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile

Pero ver este puesto por los inconvenientes de random.shuffle() de pitón. No va a funcionar bien con muchos (más de 2080) elementos.

En relación con la respuesta de Jim:

Mi ~/.bashrc contiene lo siguiente:

unsort ()
{
    LC_ALL=C sort -R "$@"
}

Con coreutils de GNU especie, -R = --random-sort, lo que genera un hash aleatoria de cada línea y las clases por ella. El hash aleatorizado no sería en realidad se utiliza en algunos lugares en algunas versiones antiguas (con errores), haciendo que devolver una salida ordenada normal, por lo que me puse LC_ALL=C.


En relación con la respuesta de Chris:

perl -MList::Util=shuffle -e'print shuffle<>'

es un poco más corto de una sola línea. (-Mmodule=a,b,c es la abreviatura de -e 'use module qw(a b c);'.)

La razón por la que le da un -i sencilla no funciona para arrastrar los pies en el lugar se debe a Perl espera que el print sucede en el mismo bucle se está leyendo el archivo y print shuffle <> no emitirá hasta después de todos los archivos de entrada han sido leer y cerrada.

Como solución más corto,

perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'

mezclará archivos en el lugar. (-n significa "envolver el código en un bucle while (<>) {...}; BEGIN{undef$/} hace Perl operan sobre archivos-en-un-tiempo en lugar de líneas-en-un-tiempo, y se necesita split/^/m porque $_=<> ha sido implícitamente hecho con un archivo completo en lugar de líneas.)

Cuando instalo coreutils con homebrew

brew install coreutils

shuf esté disponible como n.

Mac OS X con DarwinPorts:

sudo port install unsort
cat $file | unsort | ...

FreeBSD tiene su propia utilidad aleatoria:

cat $file | random | ...

Es en / usr / juegos / al azar, por lo que si usted no ha instalado juegos, usted está fuera de suerte.

Se podría considerar la instalación de puertos como textproc / rand o textproc / msort. Estos también puede estar disponible en Linux y / o Mac OS X, si la portabilidad es una preocupación.

En OSX, agarrando último de http://ftp.gnu.org/gnu/coreutils/ y algo así como

./ configure hacer sudo make install

... debe darle / usr / local / bin / tipo --random-sort

sin estropear / usr / bin / sort

O obtenerlo de MacPorts:

$ sudo port install coreutils

y / o

$ /opt/local//libexec/gnubin/sort --random-sort
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top