¿Cómo puedo aleatorizar las líneas en un archivo usando herramientas estándar en Red Hat Linux?
No tengo el shufcomando, así que estoy buscando algo como una perlo awkuna línea que logre la misma tarea.
¿Cómo puedo aleatorizar las líneas en un archivo usando herramientas estándar en Red Hat Linux?
No tengo el shufcomando, así que estoy buscando algo como una perlo awkuna línea que logre la misma tarea.
Respuestas:
¡Y obtienes un one-liner de Perl!
perl -MList::Util -e 'print List::Util::shuffle <>'
Utiliza un módulo, pero el módulo es parte de la distribución del código Perl. Si eso no es lo suficientemente bueno, puede considerar lanzar el suyo.
Intenté usar esto con la -ibandera ("editar en el lugar") para que editara el archivo. La documentación sugiere que debería funcionar, pero no es así. Todavía muestra el archivo mezclado en stdout, pero esta vez elimina el original. Le sugiero que no lo use.
Considere un script de 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 con suerte funciona.
ruby -e 'puts STDIN.readlines.shuffle'. Sería necesario realizar pruebas en grandes entradas para ver si la velocidad es comparable. (también funciona en OS X)
shufcarga todo en la memoria, por lo que no funciona con un archivo realmente enorme (el mío es ~ 300GB tsv). Este script de Perl también falló en el mío, pero sin ningún error excepto Killed. ¿Alguna idea de si la solución de Perl también está cargando todo en la memoria, o hay algún otro problema que estoy encontrando?
Um, no olvidemos
sort --random-sort
brew install coreutilstodas las utilidades tienen el prefijo ag así: gsort --random-sorto gshuffuncionarán como se esperaba
gsorte gshufinstalé cuando lo hiceport install coreutils
shuflugar (en Linux).
shuf Es la mejor manera.
sort -Res dolorosamente lento. Intenté ordenar el archivo de 5GB. Me di por vencido después de 2,5 horas. Luego lo shufordené en un minuto.
sort -Res lenta es que calcula un hash para cada línea. De los documentos: " Ordene por hash de las claves de entrada y luego clasifique los valores hash " .
shufcarga todo en la memoria.
seq -f 'line %.0f' 1000000tomó el mismo, a largo tiempo de proceso (mucho, mucho más tiempo que con shuf), sin importar la cantidad de memoria Asigné.
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Lea el archivo, anteponga cada línea con un número aleatorio, ordene el archivo por esos prefijos aleatorios, luego corte los prefijos. Una línea que debería funcionar en cualquier caparazón semi-moderno.
EDITAR: incorporó los comentarios de Richard Hansen.
$RANDOM), pero -1 para eliminar los datos. Reemplazar while read fcon while IFS= read -r fevitará readque se eliminen los espacios en blanco iniciales y finales (consulte esta respuesta ) y evitará el procesamiento de barras invertidas. El uso de una cadena aleatoria de longitud fija evitará que se cuteliminen los espacios en blanco iniciales. Resultado: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Una sola línea para Python:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile
Y para imprimir una sola línea aleatoria:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile
Pero vea esta publicación para conocer los inconvenientes de python random.shuffle(). No funcionará bien con muchos elementos (más de 2080).
Relacionado con la respuesta de Jim:
Mi ~/.bashrccontiene lo siguiente:
unsort ()
{
LC_ALL=C sort -R "$@"
}
Con sort, -R= de GNU coreutils --random-sort, que genera un hash aleatorio de cada línea y las ordena. El hash aleatorio en realidad no se usaría en algunas configuraciones regionales en algunas versiones más antiguas (con errores), lo que hace que devuelva una salida ordenada normal, por lo que configuré LC_ALL=C.
Relacionado con la respuesta de Chris:
perl -MList::Util=shuffle -e'print shuffle<>'
es un delineador ligeramente más corto. ( -Mmodule=a,b,ces la abreviatura de -e 'use module qw(a b c);'.)
La razón por la que darle un simple -ino funciona para barajar en el lugar es porque Perl espera que printsuceda en el mismo bucle en el que se está leyendo el archivo, y print shuffle <>no genera salida hasta que todos los archivos de entrada se han leído y cerrado.
Como solución temporal más breve,
perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'
mezclará los archivos en su lugar. ( -nsignifica "envolver el código en un while (<>) {...}bucle; BEGIN{undef$/}hace que Perl opere en archivos a la vez en lugar de líneas a la vez, y split/^/mes necesario porque $_=<>se ha hecho implícitamente con un archivo completo en lugar de líneas).
FreeBSD tiene su propia utilidad aleatoria:
cat $file | random | ...
Está en / usr / games / random, así que si no ha instalado juegos, no tiene suerte.
Podría considerar instalar puertos como textproc / rand o textproc / msort. Estos pueden estar disponibles en Linux y / o Mac OS X, si la portabilidad es una preocupación.
En OSX, obteniendo lo último de http://ftp.gnu.org/gnu/coreutils/ y algo como
./configure make sudo make install
... debería darle / usr / local / bin / sort --random-sort
sin estropear / usr / bin / sort
O consígalo en MacPorts:
$ sudo port install coreutils
y / o
$ /opt/local//libexec/gnubin/sort --random-sort