Come posso randomizzare le righe in un file utilizzando strumenti standard su Red Hat Linux?
Non ho il shufcomando, quindi sto cercando qualcosa come una riga perlo awkuna riga che svolga lo stesso compito.
Come posso randomizzare le righe in un file utilizzando strumenti standard su Red Hat Linux?
Non ho il shufcomando, quindi sto cercando qualcosa come una riga perlo awkuna riga che svolga lo stesso compito.
Risposte:
E ottieni una battuta in Perl!
perl -MList::Util -e 'print List::Util::shuffle <>'
Usa un modulo, ma il modulo fa parte della distribuzione del codice Perl. Se questo non è abbastanza buono, potresti prendere in considerazione l'idea di rotolare il tuo.
Ho provato a usarlo con il -iflag ("edit-in-place") per farlo modificare il file. La documentazione suggerisce che dovrebbe funzionare, ma non è così. Visualizza ancora il file mescolato allo stdout, ma questa volta elimina l'originale. Ti suggerisco di non usarlo.
Considera uno script di 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 testato, ma si spera che funzioni.
ruby -e 'puts STDIN.readlines.shuffle'. Avrebbe bisogno di test su grandi input per vedere se la velocità è comparabile. (funziona anche su OS X)
shufcarica tutto in memoria, quindi non funziona con un file veramente enorme (il mio è ~ 300 GB tsv). Anche questo script perl è fallito sul mio, ma senza errori tranne Killed. Qualche idea se la soluzione perl sta caricando tutto anche in memoria, o c'è qualche altro problema che sto riscontrando?
Um, non dimentichiamolo
sort --random-sort
brew install coreutilstutte le utilità hanno il prefisso ag quindi: gsort --random-sorto gshuffunzionerà come previsto
gsorte gshufinstallato quando l'ho fattoport install coreutils
shufinvece (su Linux).
shuf è il modo migliore.
sort -Rè dolorosamente lento. Ho appena provato a ordinare il file da 5 GB. Ho rinunciato dopo 2,5 ore. Quindi shufrisolto in un minuto.
sort -Rsia lento è che calcola un hash per ogni riga. Dai documenti: " Ordina per hash delle chiavi di input e poi ordina i valori hash. "
shufcarica tutto in memoria.
seq -f 'line %.0f' 1000000ha richiesto lo stesso, molto tempo per l'elaborazione (molto, molto più a lungo rispetto a shuf), indipendentemente dalla quantità di memoria allocata.
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Leggi il file, aggiungi un numero casuale all'inizio di ogni riga, ordina il file su quei prefissi casuali, poi taglia i prefissi. One-liner che dovrebbe funzionare in qualsiasi shell semi-moderna.
EDIT: ha incorporato le osservazioni di Richard Hansen.
$RANDOM), ma -1 per la macellazione dei dati. La sostituzione while read fcon while IFS= read -r fimpedirà la readrimozione di spazi bianchi iniziali e finali (vedere questa risposta ) e impedirà l'elaborazione di barre rovesciate. L'uso di una stringa casuale di lunghezza fissa impedirà l' cuteliminazione degli spazi bianchi iniziali. Risultato: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Una riga di testo per Python:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile
E per stampare solo una singola riga casuale:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile
Ma guarda questo post per gli svantaggi di Python random.shuffle(). Non funzionerà bene con molti (più di 2080) elementi.
In relazione alla risposta di Jim:
Il mio ~/.bashrccontiene quanto segue:
unsort ()
{
LC_ALL=C sort -R "$@"
}
Con l'ordinamento di GNU coreutils, -R= --random-sort, che genera un hash casuale di ogni riga e ordina in base ad esso. L'hash randomizzato non sarebbe stato effettivamente utilizzato in alcune versioni locali in alcune versioni precedenti (buggy), causando la restituzione di un normale output ordinato, motivo per cui ho impostato LC_ALL=C.
In relazione alla risposta di Chris:
perl -MList::Util=shuffle -e'print shuffle<>'
è un one-liner leggermente più corto. ( -Mmodule=a,b,cè una scorciatoia per-e 'use module qw(a b c);' .)
Il motivo per cui -inon funziona per lo shuffling sul posto è perché Perl si aspetta che ciò printavvenga nello stesso ciclo in cui il file viene letto, eprint shuffle <> non viene prodotto finché tutti i file di input non sono stati letti e chiusi.
Come soluzione più breve,
perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'
mescolerà i file sul posto. ( -nsignifica "avvolgere il codice in un while (<>) {...}ciclo; BEGIN{undef$/}fa sì che Perl operi su file alla volta invece che su righe alla volta, ed split/^/mè necessario perché $_=<>è stato implicitamente fatto con un intero file invece che con le righe.)
FreeBSD ha la sua utilità casuale:
cat $file | random | ...
È in / usr / games / random, quindi se non hai installato giochi, sei sfortunato.
Potresti considerare l'installazione di porte come textproc / rand o textproc / msort. Questi potrebbero essere disponibili su Linux e / o Mac OS X, se la portabilità è un problema.
Su OSX, prendendo le ultime da http://ftp.gnu.org/gnu/coreutils/ e qualcosa di simile
./configure make sudo make install
... dovrebbe darti / usr / local / bin / sort --random-sort
senza rovinare / usr / bin / sort
Oppure scaricalo da MacPorts:
$ sudo port install coreutils
e / o
$ /opt/local//libexec/gnubin/sort --random-sort