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.
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.
Hum, n'oublie pas
sort --random-sort
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.
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.
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).
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.)
Quand j'installe coreutils avec homebrew
brew install coreutils
shuf
devient disponible sous la forme n
.
Mac OS X avec DarwinPorts:
Sudo port install unsort
cat $file | unsort | ...
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.