Comment puis-je les lignes dans randomiser un fichier à l'aide des outils standard sur Red Hat Linux?

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

Question

Comment puis-je les lignes dans randomiser un fichier à l'aide des outils standard Red Hat Linux?

Je n'ai pas la commande shuf, donc je suis à la recherche de quelque chose comme un perl ou awk une doublure qui accomplit la même tâche.

Était-ce utile?

La solution

Et un Perl promotionnel que vous obtenez!

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

Il utilise un module, mais le module fait partie de la distribution de code Perl. Si ce n'est pas assez bon, vous pouvez envisager de rouler vos propres.

J'ai essayé d'utiliser ce avec le drapeau de -i ( « modifier en place ») pour l'avoir modifier le fichier. La documentation donne à penser qu'il devrait fonctionner, mais il ne fonctionne pas. Il affiche toujours le fichier brassé à stdout, mais cette fois-ci supprime l'original. Je vous suggère de ne pas l'utiliser.

Considérons un script 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

Non testé, mais fonctionne avec espoir.

Autres conseils

Um, permet de ne pas oublier

sort --random-sort

shuf est la meilleure façon.

sort -R est douloureusement lent. Je viens d'essayer de trier le fichier 5GB. J'ai abandonné au bout de 2,5 heures. Puis shuf il triée dans une minute.

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

Lire le fichier, faites précéder chaque ligne avec un nombre aléatoire, trier le fichier sur ces préfixes aléatoires, couper les préfixes après. En une ligne qui devrait fonctionner dans une coque semi-moderne.

EDIT:. Incorporé les remarques de Richard Hansen

A one-liner pour python:

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

Et pour l'impression juste une seule ligne au hasard:

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

Mais voyez cette post pour les inconvénients de la random.shuffle() de python. Il ne fonctionne pas bien avec beaucoup (plus de 2080) éléments.

associés à la réponse de Jim:

Mon ~/.bashrc contient les éléments suivants:

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

Avec le tri de GNU coreutils, -R = --random-sort, qui génère un hachage aléatoire de chaque ligne et trie par elle. Les versions de hachage aléatoire ne sont pas utilisés couramment dans certains endroits dans certains anciens (buggy), faisant revenir la sortie normale trié, ce qui est la raison pour laquelle je mets LC_ALL=C.


associés à la réponse de Chris:

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

est en une ligne un peu plus courte. (-Mmodule=a,b,c est un raccourci pour -e 'use module qw(a b c);'.)

La raison en lui donnant d'un simple -i ne fonctionne pas pour le remaniement en place est parce que Perl attend à ce que le print arrive dans la même boucle que le fichier est en cours de lecture, et print shuffle <> ne sortie qu'après les fichiers d'entrée ont tous été lire et fermé.

Pour contourner ce problème plus courte,

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

va mélanger les fichiers en place. (-n signifie « envelopper le code dans une boucle de while (<>) {...}, BEGIN{undef$/} fait Perl fonctionner sur des fichiers-à-un-temps au lieu de lignes-à-un-temps et split/^/m est nécessaire parce que $_=<> a été fait implicitement avec un dossier complet au lieu de lignes).

Lors de l'installation coreutils avec homebrew

brew install coreutils

shuf devient disponible n.

Mac OS X avec DarwinPorts:

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

FreeBSD a sa propre utilité aléatoire:

cat $file | random | ...

Il est dans / usr / jeux / aléatoire, donc si vous n'avez pas installé des jeux, vous êtes hors de la chance.

Vous pouvez envisager d'installer des ports comme textproc / rand ou textproc / msort. Celles-ci pourraient bien être disponibles sur Linux et / ou Mac OS X, si la portabilité est une préoccupation.

Sur Mac OS X, saisissant des dernières nouvelles de http://ftp.gnu.org/gnu/coreutils/ et quelque chose comme

./ configure faire sudo make install

... devrait vous donner / usr / local / bin / trier --random tri

sans chambouler / usr / bin / trier

Ou obtenir de MacPorts:

$ sudo port install coreutils

et / ou

$ /opt/local//libexec/gnubin/sort --random-sort
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top