mischiare casualmente i file in bash

Ho alcuni file in linux. Ad esempio 2 e ho bisogno di mischiare i file in un unico file.

Per esempio

$cat file1 line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 

e

 $cat file2 linea one linea two linea three linea four linea five linea six linea seven linea eight 

E più tardi, mescolando i due file, posso ottenere qualcosa del tipo:

 linea eight line 4 linea five line 1 linea three line 8 linea seven line 5 linea two linea one line 2 linea four line 7 linea six line 1 line 6 

Dovresti usare shuf command =)

 cat file1 file2 | shuf 

O con Perl:

 cat file1 file2 | perl -MList::Util=shuffle -wne 'print shuffle <>;' 

Ordinare:

 cat file1 file2 | sort -R 

SHUF:

 cat file1 file2 | shuf 

Perl:

 cat file1 file2 | perl -MList::Util=shuffle -e 'print shuffle' 

BASH:

 cat file1 file2 | while IFS= read -r line do printf "%06d %s\n" $RANDOM "$line" done | sort -n | cut -c8- 

awk:

 cat file1 file2 | awk 'BEGIN{srand()}{printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8- 

Solo una nota per gli utenti di OS X che usano MacPorts: il comando shuf è parte di coreutils ed è installato sotto il nome gshuf .

 $ sudo port install coreutils $ gshuf example.txt # or cat example.txt | gshuf 

Ecco un one-liner che non si basa su shuf o sort -R , che non avevo sul mio Mac:

 while read line; do echo $RANDOM $line; done < my_file | sort -n | cut -f2- -d' ' 

Questo esegue l'iterazione su tutte le righe in my_file e li ristampa in ordine casuale.

Vorrei usare anche shuf .

un’altra opzione, l’ordinamento di gnu ha:

  -R, --random-sort sort by random hash of keys 

potresti provare:

 cat file1 file2|sort -R 

Non è necessario utilizzare i tubi qui. Ordina da solo fa questo con il file (s) come parametri. Lo farei e basta

 sort -R file1 

o se hai più file

 sort -R file1 file2 

Questo ha funzionato per me. Impiega la mescolanza di Fisher-Yates.

 randomize() { arguments=("[email protected]") declare -a out i="$#" j="0" while [[ $i -ge "0" ]] ; do which=$(random_range "0" "$i") out[j]=${arguments[$which]} arguments[!which]=${arguments[i]} (( i-- )) (( j++ )) done echo ${out[*]} } random_range() { low=$1 range=$(($2 - $1)) if [[ range -ne 0 ]]; then echo $(($low+$RANDOM % $range)) else echo "$1" fi } 

E ‘chiaramente biased rand (come metà del tempo in cui la lista inizierà con la prima riga) ma per qualche randomizzazione di base con solo builtin bash suppongo che stia bene? Basta stampare ogni riga sì / no quindi stampare il resto …

 shuffle() { local IFS=$'\n' tail= while read l; do if [ $((RANDOM%2)) = 1 ]; then echo "$l" else tail="${tail}\n${l}" fi done < $1 printf "${tail}\n" }