Как я могу рандомизировать строки в файле, используя стандартные инструменты в Red Hat Linux? - PullRequest
93 голосов
/ 20 мая 2009

Как я могу рандомизировать строки в файле, используя стандартные инструменты в Red Hat Linux?

У меня нет команды shuf, поэтому я ищу что-то вроде perl или awk с одной строкой, которая выполняет ту же задачу.

Ответы [ 11 ]

196 голосов
/ 20 мая 2009

Хм, давайте не будем забывать

sort --random-sort
107 голосов
/ 10 февраля 2012

shuf - лучший способ.

sort -R мучительно медленно. Я просто попытался отсортировать 5 ГБ файл. Я сдался через 2,5 часа. Затем shuf отсортировал его за минуту.

62 голосов
/ 20 мая 2009

И Perl однострочный вы получаете!

perl -MList::Util -e 'print List::Util::shuffle <>'

Он использует модуль, но модуль является частью распределения кода 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

Не проверено, но, надеюсь, работает.

21 голосов
/ 20 мая 2009
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-

Чтение файла, добавление к каждой строке случайного числа, сортировка файла по этим случайным префиксам, последующее их сокращение. Однострочник, который должен работать в любой полу-современной оболочке.

РЕДАКТИРОВАТЬ: включены замечания Ричарда Хансена.

9 голосов
/ 11 июля 2013

Однострочник для 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's random.shuffle(). Он не будет хорошо работать со многими (более 2080) элементами.

5 голосов
/ 20 мая 2009

Относится к ответу Джима:

My ~/.bashrc содержит следующее:

unsort ()
{
    LC_ALL=C sort -R "$@"
}

С сортировкой 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 <> не выводится до тех пор, пока после того, как все входные файлы были прочитаны и закрыты.

В качестве более короткого решения,

perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'

будет перетасовывать файлы на месте. (-n означает «обернуть код в цикл while (<>) {...}; BEGIN{undef$/} заставляет Perl работать с файлами за раз вместо строк за разом, а split/^/m необходим, потому что $_=<> неявно сделано с целым файлом вместо строк.)

3 голосов
/ 11 апреля 2013

Когда я устанавливаю coreutils с помощью homebrew

brew install coreutils

shuf становится доступным как n.

1 голос
/ 16 июля 2013

FreeBSD имеет собственную случайную утилиту:

cat $file | random | ...

Он находится в / usr / games / random, поэтому если вы не установили игры, вам не повезло.

Вы можете установить такие порты, как textproc / rand или textproc / msort. Они вполне могут быть доступны в Linux и / или Mac OS X, если проблема заключается в переносимости.

1 голос
/ 16 июля 2013

Mac OS X с DarwinPorts:

sudo port install unsort
cat $file | unsort | ...
0 голосов
/ 14 октября 2011

Или получите его от MacPorts:

$ sudo port install coreutils

и / или

$ /opt/local//libexec/gnubin/sort --random-sort
...