Он использует модуль, но он является частью дистрибутива кода Perl. Если этого недостаточно, вы можете попробовать прокатить свой собственный.
Я пробовал использовать это с -iфлагом («редактировать на месте»), чтобы он редактировал файл. Документация предполагает, что это должно работать, но это не так. Он по-прежнему отображает перетасованный файл в стандартный вывод, но на этот раз удаляет оригинал. Я предлагаю вам не использовать его.
Рассмотрим сценарий оболочки:
#!/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
Чтобы сделать резервную копию исходного файла, вы можете добавить
Стив Шнепп,
Я обычно не поклонник Perl, но наткнулся на этот рубинового пример , который имеет преимущество быть короче: ruby -e 'puts STDIN.readlines.shuffle'. Потребуется тестирование на больших входах, чтобы увидеть, сопоставима ли скорость. (также работает на OS X)
mivk
на комментарий ниже, shufзагружает все в память, поэтому он не работает с действительно огромным файлом (у меня ~ 300 ГБ tsv). Этот сценарий perl не удался и у меня, но без ошибок, кроме Killed. Есть идеи, загружает ли решение Perl все в память или есть какая-то другая проблема, с которой я сталкиваюсь?
Ну, я использую gnu-coreutils 7.1 (стандартная установка gentoo), в котором есть сортировка с этой опцией, не знаю, когда она появилась, или есть ли она в других реализациях.
Джим Т.
1
Эта функция была реализована 10 декабря 2005 г., следующим за ней был выпуск 5.94, так что я предполагаю, что она доступна с этой версии.
Джим Т.
41
В OS X вы можете установить gnu coreutils с помощью homebrew: brew install coreutilsвсе утилиты имеют префикс ag, поэтому: gsort --random-sortили gshufбудут работать должным образом,
Майк
3
+1 @mike. Я использую Macports, и у меня тоже было gsortи gshufустановлено, когда я это делалport install coreutils
Ной Сассман
10
Это решение подходит только в том случае, если в ваших строках нет повторов. Если они это сделают, все экземпляры этой строки появятся рядом друг с другом. Рассмотрите возможность использования shufвместо этого (в Linux).
Али Джей
119
shuf это лучший способ.
sort -Rмучительно медленно. Я просто пробовал отсортировать файл размером 5ГБ. Я сдался через 2,5 часа. Потом shufразобрал за минуту.
@benroth: Насколько я могу судить, при действительно большом количестве входных данных увеличение памяти может несколько помочь , но в целом это все еще медленное. В моих тестах сортировка входного файла длиной в 1 миллион строк, созданного с помощью, seq -f 'line %.0f' 1000000занимала одинаково много времени для обработки (намного, намного дольше, чем с помощью shuf), независимо от того, сколько памяти я выделил.
mklement0
1
@ mklement0, ты прав! Я просто попробовал это с файлом гораздо большего размера, чем был раньше, и хеширование, похоже, действительно является узким местом.
Прочтите файл, добавьте к каждой строке случайное число, отсортируйте файл по этим случайным префиксам, затем удалите префиксы. Однострочный, который должен работать в любой полусовременной оболочке.
РЕДАКТИРОВАТЬ: включены замечания Ричарда Хансена.
Это работает и является творческим решением, но удаляет ведущие пробелы в строках.
Крис Лутц,
@Chris, изменив последний фрагмент на | sed 's / ^ [^ \ t] * \ t //', должен это исправить
bdonlan
Престижность простоте подхода!
Шашикант Коре
3
+1 для соответствия POSIX (кроме $RANDOM), но -1 для уничтожения данных. Замена while read fна while IFS= read -r fпредотвратит readудаление начальных и конечных пробелов (см. Этот ответ ) и предотвратит обработку обратных косых черт. Использование случайной строки фиксированной длины предотвратит cutудаление начальных пробелов. Результат: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Ричард Хансен,
3
@ Ричард Хансен: Спасибо, предлагаемые изменения, очевидно, подходят, я отредактировал свой пост.
С сортировкой GNU coreutils, -R= --random-sort, которая генерирует случайный хэш каждой строки и сортирует по нему. Рандомизированный хеш на самом деле не будет использоваться в некоторых локали в некоторых более старых (глючных) версиях, в результате чего он будет возвращать нормальный отсортированный вывод, поэтому я установил LC_ALL=C.
Относится к ответу Криса:
perl -MList::Util=shuffle -e'print shuffle<>'
является немного более коротким однострочником. ( -Mmodule=a,b,cсокращение от -e 'use module qw(a b c);'.)
Причина, по которой простота -iне работает для перетасовки на месте, заключается в том, что Perl ожидает, что это printпроизойдет в том же цикле, в котором читается файл, и print shuffle <>не выводит данные до тех пор, пока все входные файлы не будут прочитаны и закрыты.
перетасует файлы на месте. ( -nозначает «заключить код в while (<>) {...}цикл; BEGIN{undef$/}заставляет Perl работать с файлами по очереди, а не по строкам, и split/^/mнеобходимо, потому что $_=<>это было неявно выполнено с целым файлом, а не со строками.)
Повторяю, что sort -R не существует в OS X, но +1 для некоторых отличных ответов Perl и отличного ответа в целом.
Крис Лутц,
Вы можете установить GNU coreutils на OS X, но (как я делал в прошлом) вы должны быть осторожны, чтобы не сломать встроенные инструменты ... При этом OP находится в Redhat Linux, в котором определенно есть GNU coreutils стандартный.
Он находится в / usr / games / random, поэтому, если вы не установили игры, вам не повезло.
Вы можете рассмотреть возможность установки таких портов, как textproc / rand или textproc / msort. Они вполне могут быть доступны в Linux и / или Mac OS X, если переносимость вызывает беспокойство.
Ответы:
И вы получите однострочник Perl!
Он использует модуль, но он является частью дистрибутива кода Perl. Если этого недостаточно, вы можете попробовать прокатить свой собственный.
Я пробовал использовать это с
-i
флагом («редактировать на месте»), чтобы он редактировал файл. Документация предполагает, что это должно работать, но это не так. Он по-прежнему отображает перетасованный файл в стандартный вывод, но на этот раз удаляет оригинал. Я предлагаю вам не использовать его.Рассмотрим сценарий оболочки:
Не проверено, но, надеюсь, работает.
источник
ruby -e 'puts STDIN.readlines.shuffle'
. Потребуется тестирование на больших входах, чтобы увидеть, сопоставима ли скорость. (также работает на OS X)shuf
загружает все в память, поэтому он не работает с действительно огромным файлом (у меня ~ 300 ГБ tsv). Этот сценарий perl не удался и у меня, но без ошибок, кромеKilled
. Есть идеи, загружает ли решение Perl все в память или есть какая-то другая проблема, с которой я сталкиваюсь?Хм, давай не забываем
источник
brew install coreutils
все утилиты имеют префикс ag, поэтому:gsort --random-sort
илиgshuf
будут работать должным образом,gsort
иgshuf
установлено, когда я это делалport install coreutils
shuf
вместо этого (в Linux).shuf
это лучший способ.sort -R
мучительно медленно. Я просто пробовал отсортировать файл размером 5ГБ. Я сдался через 2,5 часа. Потомshuf
разобрал за минуту.источник
sort -R
медленная в том, что вычисляет хэш для каждой строки. Из документации: « Сортировка путем хеширования ключей ввода, а затем сортировки хеш-значений »shuf
загружает все в память.seq -f 'line %.0f' 1000000
занимала одинаково много времени для обработки (намного, намного дольше, чем с помощьюshuf
), независимо от того, сколько памяти я выделил.Прочтите файл, добавьте к каждой строке случайное число, отсортируйте файл по этим случайным префиксам, затем удалите префиксы. Однострочный, который должен работать в любой полусовременной оболочке.
РЕДАКТИРОВАТЬ: включены замечания Ричарда Хансена.
источник
$RANDOM
), но -1 для уничтожения данных. Заменаwhile read f
наwhile IFS= read -r f
предотвратитread
удаление начальных и конечных пробелов (см. Этот ответ ) и предотвратит обработку обратных косых черт. Использование случайной строки фиксированной длины предотвратитcut
удаление начальных пробелов. Результат:cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Однострочник для Python:
А для печати только одной случайной строки:
Но посмотрите этот пост о недостатках python
random.shuffle()
. Он не будет работать со многими (более 2080) элементами.источник
Связано с ответом Джима:
My
~/.bashrc
содержит следующее:С сортировкой GNU coreutils,
-R
=--random-sort
, которая генерирует случайный хэш каждой строки и сортирует по нему. Рандомизированный хеш на самом деле не будет использоваться в некоторых локали в некоторых более старых (глючных) версиях, в результате чего он будет возвращать нормальный отсортированный вывод, поэтому я установилLC_ALL=C
.Относится к ответу Криса:
является немного более коротким однострочником. (
-Mmodule=a,b,c
сокращение от-e 'use module qw(a b c);'
.)Причина, по которой простота
-i
не работает для перетасовки на месте, заключается в том, что Perl ожидает, что этоprint
произойдет в том же цикле, в котором читается файл, иprint shuffle <>
не выводит данные до тех пор, пока все входные файлы не будут прочитаны и закрыты.В качестве более короткого обходного пути
перетасует файлы на месте. (
-n
означает «заключить код вwhile (<>) {...}
цикл;BEGIN{undef$/}
заставляет Perl работать с файлами по очереди, а не по строкам, иsplit/^/m
необходимо, потому что$_=<>
это было неявно выполнено с целым файлом, а не со строками.)источник
Когда я устанавливаю coreutils с помощью homebrew
shuf
становится доступным какn
.источник
g
такshuf
сталоgshuf
для меня.Mac OS X с DarwinPorts:
источник
FreeBSD имеет свою собственную случайную утилиту:
Он находится в / usr / games / random, поэтому, если вы не установили игры, вам не повезло.
Вы можете рассмотреть возможность установки таких портов, как textproc / rand или textproc / msort. Они вполне могут быть доступны в Linux и / или Mac OS X, если переносимость вызывает беспокойство.
источник
В OSX скачивание последней версии с http://ftp.gnu.org/gnu/coreutils/ и чего-то вроде
./configure сделать sudo make install
... должен дать вам / usr / local / bin / sort --random-sort
без ошибок / usr / bin / sort
источник
Или получите его с MacPorts:
и / или
источник