Да, есть и другие хорошие ответы на этот оригинальный вопрос.
Руджеро Спирман
Итак, вы делали список слов wpa? (просто случайное предположение)
thahgr
Ответы:
361
Вы можете использовать shuf. По крайней мере, в некоторых системах (похоже, не в POSIX).
Как указал Джлеедев, sort -Rэто тоже может быть вариантом. По крайней мере, в некоторых системах; ну, вы поняли. Было отмечено, что на sort -Rсамом деле это не случайный случай, а сортировка элементов по их хэш-значению.
[Примечание редактора: sort -Rпочти тасуется, за исключением того, что дублирующие строки / ключи сортировки всегда оказываются рядом друг с другом . Другими словами: только с уникальными входными строками / клавишами это настоящая случайность. Хотя порядок вывода определяется значениями хеш-функции , случайность определяется выбором случайной хэш- функции - см. Руководство .]
shufи sort -Rнемного отличаются, потому что sort -Rслучайным образом упорядочивает элементы в соответствии с их хешем , то есть sort -Rобъединяет повторяющиеся элементы, в то время как shufвсе элементы перемешиваются случайным образом.
СЕМЕХ
146
Для пользователей OS X:, brew install coreutilsзатем используйте gshuf ...(:
ELLIOTTCABLE
15
sort -Rи shufдолжен рассматриваться как совершенно другой. sort -Rявляется детерминированным. Если вы вызываете его дважды в разное время на одном и том же входе, вы получите один и тот же ответ. shufс другой стороны, производит случайный вывод, так что он, скорее всего, будет давать разные выходные данные на одном и том же входе.
EfForEffort
18
Это не правильно. «sort -R» использует разные случайные хэш-ключи каждый раз, когда вы вызываете его, поэтому каждый раз выдает разные выходные данные.
Марк Петтит
3
Примечание о случайности: согласно документации GNU: «По умолчанию эти команды используют внутренний псевдослучайный генератор, инициализированный небольшой энтропией, но могут быть направлены на использование внешнего источника с параметром --random-source = file».
Ройс Уильямс
86
Perl one-liner будет простой версией решения Максима
Это был единственный скрипт на этой странице, который возвращал РЕАЛЬНЫЕ случайные строки. Другие решения awk часто выводят дубликаты.
Фелипе Альварес
1
Но будьте осторожны, потому что на выходе вы потеряете одну строку :) Она просто будет соединена с другой строкой :)
JavaRunner
@JavaRunner: я полагаю, вы говорите о вводе без трейлинга \n; да, это \nдолжно присутствовать - и это , как правило , это - в противном случае вы получите то , что вы описываете.
mklement0
1
Чудесно лаконично. Я предлагаю заменить <STDIN>на <>, так что решение работает и с вводом из файлов .
mklement0
60
Этот ответ дополняет многие великие существующие ответы следующими способами:
Существующие ответы упакованы в гибкие функции оболочки :
Функции принимают не только stdinввод, но также и аргументы имени файла
Функции выполняют дополнительные шаги для обработки SIGPIPEобычным способом (тихое завершение с кодом выхода 141), в отличие от шумного взлома. Это важно при передаче вывода функции в трубу, которая закрывается раньше, например, при передаче в head.
Сравнение производительности производится.
POSIX-совместимая функция , основанная на awk, sortиcut , адаптировано из собственного ответа OP в :
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))
'"$@";}
См. Нижний раздел для версии Windows для этой функции.
Примечание. Эти цифры были получены на iMac, выпущенном в конце 2012 года, с процессором Intel Core i5 с тактовой частотой 3,2 ГГц и диском Fusion, работающим под управлением OSX 10.10.3. Хотя время будет зависеть от используемой ОС, технических характеристик машины, awkиспользуемой реализации (например, awkверсия BSD, используемая в OSX, обычно медленнее, чем GNU awkи особенно mawk), это должно дать общее представление об относительной производительности .
Входной файл представляет собой файл с 1 миллионом строк, созданный с помощью seq -f 'line %.0f' 1000000.
Время указано в порядке возрастания (сначала самое быстрое):
shuf
0.090s
Ruby 2.0.0
0.289s
Perl 5.18.2
0.589s
питон
1.342sс Python 2.7.6; 2.407s(!) с Python 3.4.2
awk+ sort+cut
3.003sс BSD awk; 2.388sс GNU awk(4.1.1); 1.811sс mawk(1.3.4);
Для дальнейшего сравнения решения не упакованы как функции выше:
sort -R (не настоящий случай, если есть повторяющиеся строки ввода)
10.661s - выделение большего количества памяти, кажется, не имеет значения
Scala
24.229s
bash петли + sort
32.593s
Выводы :
Используйте shuf, если можете - это самый быстрый на сегодняшний день.
Руби хорошо, а затем Perl .
Python заметно медленнее, чем Ruby и Perl, и, сравнивая версии Python, 2.7.6 немного быстрее, чем 3.4.1
Используйте POSIX-совместимый awk+ sort+ cutкомбо в крайнем случае ; какая awkреализация вы используете, имеет значение ( mawkбыстрее, чем GNU awk, BSD awkмедленнее).
Держись подальше sort -R, bashпетли и Скала.
Версии решения Python для Windows (код Python идентичен, за исключением различий в кавычках и удалении операторов, связанных с сигналами, которые не поддерживаются в Windows):
Для PowerShell (в Windows PowerShell вам придется настроить, $OutputEncodingесли вы хотите отправлять не-ASCII символы через конвейер):
# Call as `shuf someFile.txt` or `Get-Content someFile.txt | shuf`function shuf {
$Input | python -c @'
import sys, random, fileinput;
lines=[line for line in fileinput.input()];
random.shuffle(lines); sys.stdout.write(''.join(lines))
'@ $args
}
Обратите внимание, что PowerShell может напрямую перетасовываться с помощью своего Get-Randomкомандлета (хотя производительность может быть проблемой); например: Get-Content someFile.txt | Get-Random -Count ([int]::MaxValue)
Для cmd.exe(пакетный файл):
Сохранить в файл shuf.cmd, например:
@echo off
python -c "import sys, random, fileinput; lines=[line for line in fileinput.input()]; random.shuffle(lines); sys.stdout.write(''.join(lines))"%*
SIGPIPE не существует в Windows, поэтому я использовал этот простой однострочный python -c "import sys, random; lines = [x for x in sys.stdin.read().splitlines()] ; random.shuffle(lines); print(\"\n\".join([line for line in lines]));"
текст
@elig: Спасибо, но достаточно опустить from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL);исходное решение и сохранить гибкость, позволяя также передавать аргументы имени файла - не нужно ничего менять (кроме цитирования) - смотрите новый раздел, который я добавил на низ.
mklement0
27
Я использую крошечный Perl-скрипт, который я называю «unsort»:
#!/usr/bin/perl
use List::Util'shuffle';@list=<STDIN>;
print shuffle(@list);
У меня также есть версия с разделением NULL, которая называется "unsort0" ... удобная для использования с find -print0 и так далее.
PS: проголосовал также за 'shuf', я понятия не имел, что было в coreutils в эти дни ... вышеупомянутое может все еще быть полезным, если в ваших системах нет 'shuf'.
Красиво сделано; Я предлагаю заменить <STDIN>с <>тем чтобы сделать работу решения с вводом из файлов тоже.
mklement0
20
Вот первая попытка, которая проста для кодера, но тяжела для процессора, который добавляет случайное число к каждой строке, сортирует их и затем удаляет случайное число из каждой строки. По сути, строки сортируются случайным образом:
Хорошо, я отлаживаю с head myfile | awk .... Тогда я просто изменяю это на кошку; вот почему он был оставлен там.
Руджеро Спирман
Не нужно -k1 -nдля сортировки, поскольку выходные данные awk rand()- это десятичные числа от 0 до 1, и потому, что все, что имеет значение, это то, что они каким-то образом переупорядочиваются. -k1может помочь ускорить его, игнорируя оставшуюся часть строки, хотя вывод rand () должен быть достаточно уникальным, чтобы замкнуть сравнение.
Бонсайвинг
@ ghostdog74: Большинство так называемых бесполезных применений cat на самом деле полезно для согласованности между переданными командами командами, а не для них. Лучше сохранить cat filename |(или < filename |), чем помнить, как каждая отдельная программа принимает входной файл (или нет).
Хорошо сделано, но на практике гораздо медленнее, чем собственный ответ ОП , который сочетается awkс sortи cut. Для не более нескольких тысяч строк это не имеет большого значения, но при большем количестве строк это имеет значение (порог зависит от используемой awkреализации). Небольшое упрощение было бы заменить строки while (1){и if (e==d) {break}с while (e<d).
«Недостаток» не является специфическим для Python. Конечные периоды PRNG можно обойти путем повторного заполнения PRNG энтропией из системы, как это /dev/urandomделается. Для того, чтобы использовать его в Python: random.SystemRandom().shuffle(L).
JFS
разве join () не должен быть в '\ n', чтобы строки печатались по-своему?
elig
@elig: Нет, потому что .readLines()возвращает строки с завершающим переводом строки.
Это должно работать практически на любой UNIX. Протестировано на Linux, Solaris и HP-UX.
Обновить:
Обратите внимание, что ведущие нули ( %06d) и rand()умножение заставляют его работать должным образом и в системах, где sortне понимают числа. Это может быть отсортировано по лексикографическому порядку (иначе как сравнение строк).
Хорошая идея - упаковать собственный ответ ОП как функцию; если вы добавите "$@", он также будет работать с файлами в качестве входных данных. Нет смысла умножать rand(), потому что sort -nспособен сортировать десятичные дроби. Это, однако, хорошая идея управления awkформатом вывода «s, потому что с форматом по умолчанию, в %.6g, rand()будет выводить случайные числа в экспоненциальной нотации. Хотя на практике, возможно, достаточно перетасовать до 1 миллиона строк, легко поддерживать большее количество строк без значительных потерь производительности; например %.17f.
mklement0
1
@ mklement0 Я не заметил ответ ОП при написании своего. Насколько я помню, rand () умножается на 10e6, чтобы он работал с солярисом или hpux. Хорошая идея с "$ @"
Михал Шрайер
1
Понял, спасибо; возможно, вы могли бы добавить это обоснование умножения к самому ответу; обычно, согласно POSIX, он sortдолжен обрабатывать десятичные дроби (даже с тысячами разделителей, как я только что заметил).
Отличный материал; Если вы используете puts ARGF.readlines.shuffle, вы можете заставить его работать как с вводом stdin, так и с аргументами имени файла.
mklement0
Еще короче ruby -e 'puts $<.sort_by{rand}'- ARGF уже перечислим, поэтому мы можем перетасовать строки, сортируя их по случайным значениям.
Акюн
6
Один лайнер для Python, основанный на ответе scai , но a) принимает stdin, b) делает результат повторяемым с помощью seed, c) выбирает только 200 из всех строк.
Это скрипт на 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 как:
Если, как и я, вы пришли сюда, чтобы найти альтернативу shufдля macOS, используйте randomize-lines.
Установить randomize-lines(homebrew) пакет, в котором есть rlкоманда, аналогичная функциональности shuf.
brew install randomize-lines
Usage: 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
Заманчиво просто, но если Java VM не должен быть запущен в любом случае, эта стоимость запуска является значительной; плохо работает с большим количеством строк.
mklement0
1
Эта функция bash имеет минимальную зависимость (только sort и bash):
Хорошее решение bash, которое аналогично собственному awkрешению OP, но производительность будет проблемой при большем вводе; использование вами одного $RANDOMзначения корректно перетасовывает только до 32 768 строк ввода; хотя вы могли бы расширить этот диапазон, это, вероятно, того не стоит: например, на моем компьютере выполнение сценария на 32 768 коротких строках ввода занимает около 1 секунды, что примерно в 150 раз больше времени выполнения shuf, и примерно в 10–15 раз. столько, сколько awkтребуется собственному решению ОП. Если вы можете положиться на sortприсутствие, awkдолжно быть там.
mklement0
0
В Windows Вы можете попробовать этот пакетный файл, чтобы помочь вам перетасовать ваш data.txt. Использование пакетного кода
C:\> type list.txt | shuffle.bat > maclist_temp.txt
После выполнения этой команды maclist_temp.txt будет содержать рандомизированный список строк.
Ответы:
Вы можете использовать
shuf
. По крайней мере, в некоторых системах (похоже, не в POSIX).Как указал Джлеедев,
sort -R
это тоже может быть вариантом. По крайней мере, в некоторых системах; ну, вы поняли. Было отмечено, что наsort -R
самом деле это не случайный случай, а сортировка элементов по их хэш-значению.[Примечание редактора:
sort -R
почти тасуется, за исключением того, что дублирующие строки / ключи сортировки всегда оказываются рядом друг с другом . Другими словами: только с уникальными входными строками / клавишами это настоящая случайность. Хотя порядок вывода определяется значениями хеш-функции , случайность определяется выбором случайной хэш- функции - см. Руководство .]источник
shuf
иsort -R
немного отличаются, потому чтоsort -R
случайным образом упорядочивает элементы в соответствии с их хешем , то естьsort -R
объединяет повторяющиеся элементы, в то время какshuf
все элементы перемешиваются случайным образом.brew install coreutils
затем используйтеgshuf ...
(:sort -R
иshuf
должен рассматриваться как совершенно другой.sort -R
является детерминированным. Если вы вызываете его дважды в разное время на одном и том же входе, вы получите один и тот же ответ.shuf
с другой стороны, производит случайный вывод, так что он, скорее всего, будет давать разные выходные данные на одном и том же входе.Perl one-liner будет простой версией решения Максима
источник
\n
; да, это\n
должно присутствовать - и это , как правило , это - в противном случае вы получите то , что вы описываете.<STDIN>
на<>
, так что решение работает и с вводом из файлов .Этот ответ дополняет многие великие существующие ответы следующими способами:
Существующие ответы упакованы в гибкие функции оболочки :
stdin
ввод, но также и аргументы имени файлаSIGPIPE
обычным способом (тихое завершение с кодом выхода141
), в отличие от шумного взлома. Это важно при передаче вывода функции в трубу, которая закрывается раньше, например, при передаче вhead
.Сравнение производительности производится.
awk
,sort
иcut
, адаптировано из собственного ответа OP в :См. Нижний раздел для версии Windows для этой функции.
Сравнение производительности:
Примечание. Эти цифры были получены на iMac, выпущенном в конце 2012 года, с процессором Intel Core i5 с тактовой частотой 3,2 ГГц и диском Fusion, работающим под управлением OSX 10.10.3. Хотя время будет зависеть от используемой ОС, технических характеристик машины,
awk
используемой реализации (например,awk
версия BSD, используемая в OSX, обычно медленнее, чем GNUawk
и особенноmawk
), это должно дать общее представление об относительной производительности .Входной файл представляет собой файл с 1 миллионом строк, созданный с помощью
seq -f 'line %.0f' 1000000
.Время указано в порядке возрастания (сначала самое быстрое):
shuf
0.090s
0.289s
0.589s
1.342s
с Python 2.7.6;2.407s
(!) с Python 3.4.2awk
+sort
+cut
3.003s
с BSDawk
;2.388s
с GNUawk
(4.1.1);1.811s
сmawk
(1.3.4);Для дальнейшего сравнения решения не упакованы как функции выше:
sort -R
(не настоящий случай, если есть повторяющиеся строки ввода)10.661s
- выделение большего количества памяти, кажется, не имеет значения24.229s
bash
петли +sort
32.593s
Выводы :
shuf
, если можете - это самый быстрый на сегодняшний день.awk
+sort
+cut
комбо в крайнем случае ; какаяawk
реализация вы используете, имеет значение (mawk
быстрее, чем GNUawk
, BSDawk
медленнее).sort -R
,bash
петли и Скала.Версии решения Python для Windows (код Python идентичен, за исключением различий в кавычках и удалении операторов, связанных с сигналами, которые не поддерживаются в Windows):
$OutputEncoding
если вы хотите отправлять не-ASCII символы через конвейер):Обратите внимание, что PowerShell может напрямую перетасовываться с помощью своего
Get-Random
командлета (хотя производительность может быть проблемой); например:Get-Content someFile.txt | Get-Random -Count ([int]::MaxValue)
cmd.exe
(пакетный файл):Сохранить в файл
shuf.cmd
, например:источник
python -c "import sys, random; lines = [x for x in sys.stdin.read().splitlines()] ; random.shuffle(lines); print(\"\n\".join([line for line in lines]));"
from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL);
исходное решение и сохранить гибкость, позволяя также передавать аргументы имени файла - не нужно ничего менять (кроме цитирования) - смотрите новый раздел, который я добавил на низ.Я использую крошечный Perl-скрипт, который я называю «unsort»:
У меня также есть версия с разделением NULL, которая называется "unsort0" ... удобная для использования с find -print0 и так далее.
PS: проголосовал также за 'shuf', я понятия не имел, что было в coreutils в эти дни ... вышеупомянутое может все еще быть полезным, если в ваших системах нет 'shuf'.
источник
<STDIN>
с<>
тем чтобы сделать работу решения с вводом из файлов тоже.Вот первая попытка, которая проста для кодера, но тяжела для процессора, который добавляет случайное число к каждой строке, сортирует их и затем удаляет случайное число из каждой строки. По сути, строки сортируются случайным образом:
источник
head myfile | awk ...
. Тогда я просто изменяю это на кошку; вот почему он был оставлен там.-k1 -n
для сортировки, поскольку выходные данные awkrand()
- это десятичные числа от 0 до 1, и потому, что все, что имеет значение, это то, что они каким-то образом переупорядочиваются.-k1
может помочь ускорить его, игнорируя оставшуюся часть строки, хотя вывод rand () должен быть достаточно уникальным, чтобы замкнуть сравнение.cat filename |
(или< filename |
), чем помнить, как каждая отдельная программа принимает входной файл (или нет).вот сценарий awk
вывод
источник
awk
сsort
иcut
. Для не более нескольких тысяч строк это не имеет большого значения, но при большем количестве строк это имеет значение (порог зависит от используемойawk
реализации). Небольшое упрощение было бы заменить строкиwhile (1){
иif (e==d) {break}
сwhile (e<d)
.Однострочник для Python:
А для печати всего одна случайная строка:
Но посмотрите этот пост на наличие недостатков Python
random.shuffle()
. Это не будет хорошо работать со многими (более 2080) элементами.источник
/dev/urandom
делается. Для того, чтобы использовать его в Python:random.SystemRandom().shuffle(L)
..readLines()
возвращает строки с завершающим переводом строки.Простая функция на основе awk сделает эту работу:
использование:
Это должно работать практически на любой UNIX. Протестировано на Linux, Solaris и HP-UX.
Обновить:
Обратите внимание, что ведущие нули (
%06d
) иrand()
умножение заставляют его работать должным образом и в системах, гдеsort
не понимают числа. Это может быть отсортировано по лексикографическому порядку (иначе как сравнение строк).источник
"$@"
, он также будет работать с файлами в качестве входных данных. Нет смысла умножатьrand()
, потому чтоsort -n
способен сортировать десятичные дроби. Это, однако, хорошая идея управленияawk
форматом вывода «s, потому что с форматом по умолчанию, в%.6g
,rand()
будет выводить случайные числа в экспоненциальной нотации. Хотя на практике, возможно, достаточно перетасовать до 1 миллиона строк, легко поддерживать большее количество строк без значительных потерь производительности; например%.17f
.sort
должен обрабатывать десятичные дроби (даже с тысячами разделителей, как я только что заметил).Ruby FTW:
источник
puts ARGF.readlines.shuffle
, вы можете заставить его работать как с вводом stdin, так и с аргументами имени файла.ruby -e 'puts $<.sort_by{rand}'
- ARGF уже перечислим, поэтому мы можем перетасовать строки, сортируя их по случайным значениям.Один лайнер для Python, основанный на ответе scai , но a) принимает stdin, b) делает результат повторяемым с помощью seed, c) выбирает только 200 из всех строк.
источник
Простой и интуитивно понятный способ будет использовать
shuf
.Пример:
Предположим
words.txt
как:Чтобы перемешать строки, выполните:
который бросил бы перемешанные строки к стандартному выводу ; Итак, вы должны передать его в выходной файл, например:
Один такой случайный ход может дать:
источник
У нас есть пакет, чтобы сделать саму работу:
Пример:
Создайте упорядоченный список номеров и сохраните его в 1000.txt:
чтобы перемешать, просто используйте
источник
Это скрипт на python, который я сохранил как rand.py в моей домашней папке:
На Mac OSX
sort -R
иshuf
не доступны, поэтому вы можете использовать псевдоним этого в вашем bash_profile как:источник
Если, как и я, вы пришли сюда, чтобы найти альтернативу
shuf
для macOS, используйтеrandomize-lines
.Установить
randomize-lines
(homebrew) пакет, в котором естьrl
команда, аналогичная функциональностиshuf
.brew install randomize-lines
источник
brew install coreutils
обеспечиваетshuf
бинарный какgshuf
.Если у вас установлен Scala, вот одна строка для перетасовки ввода:
источник
Эта функция bash имеет минимальную зависимость (только sort и bash):
источник
awk
решению OP, но производительность будет проблемой при большем вводе; использование вами одного$RANDOM
значения корректно перетасовывает только до 32 768 строк ввода; хотя вы могли бы расширить этот диапазон, это, вероятно, того не стоит: например, на моем компьютере выполнение сценария на 32 768 коротких строках ввода занимает около 1 секунды, что примерно в 150 раз больше времени выполненияshuf
, и примерно в 10–15 раз. столько, сколькоawk
требуется собственному решению ОП. Если вы можете положиться наsort
присутствие,awk
должно быть там.В Windows Вы можете попробовать этот пакетный файл, чтобы помочь вам перетасовать ваш data.txt. Использование пакетного кода
После выполнения этой команды maclist_temp.txt будет содержать рандомизированный список строк.
Надеюсь это поможет.
источник
Пока не упоминается:
unsort
Util. Синтаксис (несколько ориентированный на плейлист):msort
может перетасовать строку, но обычно это перебор:источник
Другой
awk
вариант:источник