19 ответов:
можно использовать
shuf. По крайней мере, на некоторых системах (похоже, не в POSIX).как jleedev указал:
sort -Rтакже может быть вариант. По крайней мере, в некоторых системах; ну, вы получите картину. было указано этоsort -Rна самом деле не перетасовывает, а сортирует элементы в соответствии с их хэш-значением.[Примечание редактора:
sort -Rпочти тасует, за исключением того, что дублировать строки / сортировка ключей всегда заканчивается рядом друг с другом. Другими словами: только с уникальный входные линии / клавиши-это настоящая перетасовка. Хотя это правда, что порядок вывода определяется хэш-значения, случайность происходит от выбора случайного хэша функции - см. руководство.]
Perl one-liner будет простой версией решения Максима
perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' < myfile
этот ответ дополняет многие великие существующие ответы следующим образом:
существующие ответы упаковано в гибкий функции оболочки:
- функции не только
stdinввод, но в качестве альтернативы также filename аргументы- функции примите дополнительные меры для обработки
SIGPIPEобычным способом (тихо завершение с кодом выхода141), в отличие от шумного разрыва. Это важно, когда функция выводится по трубопроводу в трубу, которая закрыта рано, например, при трубопроводе вhead.A сравнение производительности сделано.
- POSIX-совместимыми}' "$@" | sort -k1,1n | cut -d ' ' -f2-; }
- Perl - на основе функции-адаптированы из Moonyoung Kang's answer:
shuf() { perl -MList::Util=shuffle -e 'print shuffle(<>);' "$@"; }
- Python-основанная функция, приспособленная от scai по:
shuf() { python -c ' import sys, random, fileinput; from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL); lines=[line for line in fileinput.input()]; random.shuffle(lines); sys.stdout.write("".join(lines)) ' "$@"; }
- Рубин-основанная функция, приспособленная от hoffmanc по ответ:
shuf() { ruby -e 'Signal.trap("SIGPIPE", "SYSTEM_DEFAULT"); puts ARGF.readlines.shuffle' "$@"; }
для сравнения:
примечание: эти цифры были получены на конце 2012 года iMac с 3,2 ГГц Intel Core i5 и Fusion Drive, под управлением OSX 10.10.3. в то время как тайминги будут варьироваться в зависимости от используемой ОС, спецификации машины,
awkреализации (например, BSDawkверсия, используемая на OSX, обычно медленнее, чем GNUawkи особенноmawk),это должно дать общее чувство относительные производительность.Input
Я использую крошечный скрипт perl, который я называю "unsort":
#!/usr/bin/perl use List::Util 'shuffle'; @list = <STDIN>; print shuffle(@list);У меня также есть версия с нулевыми разделителями, называемая "unsort0" ... удобный для использования с find-print0 и так далее.
PS: проголосовали за " Шуф " тоже, я понятия не имел, что было в coreutils в эти дни ... вышеизложенное может быть полезно, если в ваших системах нет "shuf".
вот первая попытка, которая легко на кодере, но трудно на процессоре, который добавляет случайное число к каждой строке, сортирует их, а затем удаляет случайное число из каждой строки. По сути, строки сортируются случайным образом:
cat myfile | awk 'BEGIN{srand();}{print rand()"\t"}' | sort -k1 -n | cut -f2- > myfile.shuffled
вот скрипт awk
awk 'BEGIN{srand() } { lines[++d]= } END{ while (1){ if (e==d) {break} RANDOM = int(1 + rand() * d) if ( RANDOM in lines ){ print lines[RANDOM] delete lines[RANDOM] ++e } } }' fileвыход
$ cat file 1 2 3 4 5 6 7 8 9 10 $ ./shell.sh 7 5 10 9 6 8 2 1 3 4
один лайнер для python:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFileи для печати только одной случайной строки:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFileно вижу этот пост для устранения недостатков в Python
random.shuffle(). Он не будет хорошо работать со многими (более 2080) элементами.
простая awk-функция сделает работу:
shuffle() { awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, ;}' | sort -n | cut -c8- }использование:
any_command | shuffleЭто должно работать практически на любом UNIX. Протестировано на Linux, Solaris и HP-UX.
обновление:
обратите внимание, что ведущие нули (
%06d) иrand()умножение делает его работать должным образом также на системах, гдеsortне понимаю цифр. Он может быть отсортирован по лексикографическому порядку (a.k.a. normal string compare).
один лайнер для Python на основе scai по, но а) принимает stdin, Б) делает результат повторяемым с семенем, в) выбирает только 200 из всех строк.
$ cat file | python -c "import random, sys; random.seed(100); print ''.join(random.sample(sys.stdin.readlines(), 200))," \ > 200lines.txt
это скрипт python, который я сохранил как rand.py в моей домашней папке:
#!/bin/python import sys import random if __name__ == '__main__': with open(sys.argv[1], 'r') as f: flist = f.readlines() random.shuffle(flist) for line in flist: print line.strip()на Mac OSX
sort -Rиshufнедоступны, так что вы можете псевдоним это в вашем bash_profile как:alias shuf='python rand.py'
у нас есть пакет, чтобы сделать саму работу:
sudo apt-get install randomize-linesпример:
создайте упорядоченный список чисел и сохраните его до 1000.txt:
seq 1000 > 1000.txtчтобы перетасовать его, просто используйте
rl 1000.txt
если, как я вы пришли сюда, чтобы искать альтернативный
shufдля macOS затем используйтеrandomize-lines.установить
randomize-lines(самогон) пакет, который имеетrlкоманда, которая имеет аналогичную функциональностьshuf.
brew install randomize-linesUsage: rl [OPTION]... [FILE]... Randomize the lines of a file (or stdin). -c, --count=N select N lines from the file -r, --reselect lines may be selected multiple times -o, --output=FILE send output to file -d, --delimiter=DELIM specify line delimiter (one character) -0, --null set line delimiter to null character (useful with find -print0) -n, --line-number print line number with output lines -q, --quiet, --silent do not output any errors or warnings -h, --help display this help and exit -V, --version output version information and exit
простой и интуитивно понятный способ будет использовать
shuf.пример:
предположим
words.txtкак:the an linux ubuntu life good breezeчтобы перетасовать строки, сделайте:
$ shuf words.txtкоторый бы бросает перетасованные строки в стандартный вывод; Итак, вы труба до выходной файл как:
$ shuf words.txt > shuffled_words.txtодин такой shuffle run может выход:
breeze the linux an ubuntu good life
Если у Вас установлен Scala, вот один лайнер для перетасовки ввода:
ls -1 | scala -e 'for (l <- util.Random.shuffle(io.Source.stdin.getLines.toList)) println(l)'
эта функция bash имеет минимальную зависимость(только сортировка и bash):
shuf() { while read -r x;do echo $RANDOM$'\x1f'$x done | sort | while IFS=$'\x1f' read -r x y;do echo $y done }
в windows вы можете попробовать этот пакетный файл чтобы помочь вам перетасовать ваши данные.txt, использование пакетного кода
C:\> type list.txt | shuffle.bat > maclist_temp.txtпосле выполнения этой команды, maclist_temp.txt будет содержать рандомизированный список строк.
надеюсь, что это помогает.
пока не упоминается:
The
unsortutil. Синтаксис (несколько ориентированный на плейлист):unsort [-hvrpncmMsz0l] [--help] [--version] [--random] [--heuristic] [--identity] [--filenames[=profile]] [--separator sep] [--concatenate] [--merge] [--merge-random] [--seed integer] [--zero-terminated] [--null] [--linefeed] [file ...]
msortможно перетасовать по строке, но это обычно перебор:seq 10 | msort -jq -b -l -n 1 -c r
другое
awkвариант:#!/usr/bin/awk -f # usage: # awk -f randomize_lines.awk lines.txt # usage after "chmod +x randomize_lines.awk": # randomize_lines.awk lines.txt BEGIN { FS = "\n"; srand(); } { lines[ rand()] = ; } END { for( k in lines ){ print lines[k]; } }
Comments