web-dev-qa-db-fra.com

Comment puis-je randomiser les lignes d'un fichier en utilisant des outils standard sur Red Hat Linux?

Comment puis-je randomiser les lignes d'un fichier en utilisant des outils standard sur Red Hat Linux?

Je n'ai pas la commande shuf, donc je cherche quelque chose comme un Perl ou awk une ligne qui accomplit la même tâche.

95
Stuart Woodward

Et un one-liner Perl 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 cela ne suffit pas, vous pouvez envisager de lancer le vôtre.

J'ai essayé d'utiliser ceci avec le -i flag ("edit-in-place") pour qu'il édite le fichier. La documentation suggère que cela devrait fonctionner, mais ce n'est pas le cas. Il affiche toujours le fichier mélangé sur stdout, mais cette fois il supprime l'original. Je vous suggère de ne pas l'utiliser.

Considérez 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 j'espère qu'il fonctionne.

62
Chris Lutz

Hum, n'oublie pas

sort --random-sort
201
Jim T

shuf est le meilleur moyen.

sort -R est douloureusement lent. Je viens d'essayer de trier un fichier de 5 Go. J'ai abandonné après 2,5 heures. shuf l'a trié en une minute.

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

Lisez le fichier, ajoutez à chaque ligne un nombre aléatoire, triez le fichier sur ces préfixes aléatoires, coupez ensuite les préfixes. Une doublure qui devrait fonctionner dans n'importe quelle coque semi-moderne.

EDIT: incorpore les remarques de Richard Hansen.

22
ChristopheD

Un one-liner pour python:

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

Et pour imprimer une seule ligne aléatoire:

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

Mais voir cet article pour les inconvénients de random.shuffle() de python. Cela ne fonctionnera pas bien avec de nombreux éléments (plus de 2080).

9
scai

En rapport avec la réponse de Jim:

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

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

Avec GNU le tri de coreutils, -R = --random-sort, Qui génère un hachage aléatoire de chaque ligne et le trie. Le hachage aléatoire ne serait pas réellement utilisé dans certains paramètres régionaux dans certaines versions plus anciennes (buggy), ce qui provoque le retour d'une sortie triée normale, c'est pourquoi j'ai défini LC_ALL=C.


En rapport avec la réponse de Chris:

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

est une doublure légèrement plus courte. (-Mmodule=a,b,c Est un raccourci pour -e 'use module qw(a b c);'.)

La raison pour laquelle lui donner un simple -i Ne fonctionne pas pour le brassage sur place est parce que Perl s'attend à ce que le print se produise dans la même boucle que le fichier est lu, et print shuffle <> ne s'affiche qu'après la lecture et la fermeture de tous les fichiers d'entrée.

Comme solution de contournement plus courte,

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

va mélanger les fichiers sur place. (-n Signifie "envelopper le code dans une boucle while (<>) {...}; BEGIN{undef$/} Fait fonctionner Perl sur des fichiers à la fois au lieu de lignes à la fois, et split/^/m est nécessaire car $_=<> a été implicitement fait avec un fichier entier au lieu de lignes.)

5
ephemient

Quand j'installe coreutils avec homebrew

brew install coreutils

shuf devient disponible sous la forme n.

3
John McDonnell

Mac OS X avec DarwinPorts:

Sudo port install unsort
cat $file | unsort | ...
1
Coroos

FreeBSD a son propre utilitaire aléatoire:

cat $file | random | ...

C'est dans/usr/games/random, donc si vous n'avez pas installé de jeux, vous n'avez pas de chance.

Vous pouvez envisager d'installer des ports comme textproc/Rand ou textproc/msort. Ceux-ci pourraient bien être disponibles sur Linux et/ou Mac OS X, si la portabilité est un problème.

1
Coroos