Я пытаюсь написать сценарий оболочки. Идея состоит в том, чтобы выбрать произвольную строку из текстового файла и отобразить ее как уведомление рабочего стола Ubuntu.
Но я хочу, чтобы при каждом выполнении сценария были выбраны разные строки. Есть ли решение для этого? Я не хочу весь сценарий. Только эта простая вещь.
scripts
text-processing
Ананду М Дас
источник
источник
Ответы:
Вы можете использовать
shuf
утилиту для печати случайных строк из файла-n
: количество строк для печатиПримеры:
источник
n
количество строк для печати. (т.е. хотите ли вы только одну строку или две строки). Не номер строки (т.е. первая строка 2-я строка).date +%S
) в переменной х, а затем выбрать эту XTH линию , используяhead
иtail
команды из текстового файла. В любом случае ваш метод проще. Спасибоshuf
в coreutils, поэтому он доступен по умолчанию. Примечание: он загружает входной файл в память. Существует эффективный алгоритм, который этого не требует .Вы также можете использовать
sort
команду, чтобы получить случайную строку из файла.источник
sort -R
дает другой результат, чемshuf -n1
илиselect-random
если во входе есть повторяющиеся строки. Смотрите комментарий @ EliahKagan .Просто для удовольствия, здесь чисто баш решение , которое не используется
shuf
,sort
,wc
,sed
,head
,tail
или любые другие внешние инструменты.Единственное преимущество по сравнению с
shuf
вариантом в том, что он немного быстрее, так как это чистый bash. На моей машине для файла из 1000 строкshuf
вариант занимает около 0,1 секунды, в то время как следующий скрипт занимает около 0,01 секунды;) Так что, хотяshuf
это самый простой и самый короткий вариант, это быстрее.Честно говоря, я все равно пошел бы на
shuf
решение, если высокая эффективность не является важной проблемой.источник
shuf
в любом случае намного лучше. Думая об этом, я не верю, что чистый bash на самом деле более эффективен, чем использованиеshuf
, как я писал ранее. При запуске внешнего инструмента могут быть минимальные (постоянные) издержки, но тогда он будет работать быстрее, чем интерпретируемый bash. Так что,shuf
конечно, весы лучше. Допустим, сценарий служит образовательным целям: приятно видеть, что это можно сделать;)shuf
специфичен для GNU Coreutils (например, не во FreeBSD 10.0).sort -R
является переносимым, но решает другую (связанную) проблему: строки, представленные в виде нескольких строк, имеют вероятность, равную тем, которые появляются только один раз. (Конечно,wc
можно использовать и другие утилиты.) Я думаю, что основным ограничением здесь является то, что после 32768-й строки ничего не выбирается (и становится менее случайным, что несколько раньше).$((RANDOM<<15|RANDOM))
есть в 0..2 ^ 30-1. @JFSebastian Этоshuf
не тоsort -R
, что склоняется к более частым входам. Поставьshuf -n 1
вместоsort -R | head -n1
и сравни. (Кстати, 10 ^ 3 итерации быстрее, чем 10 ^ 6, и все же вполне достаточно, чтобы показать разницу.) См. Также более грубую, более наглядную демонстрацию и этот кусочек глупости, показывающий, что он работает на больших входах, где все строки имеют высокую частоту .dieharder
видимому, являются все нули. Если предположить, что это не просто какая-то странная ошибка с моей стороны, это наверняка объяснит, почему это не случайно! Получаете ли вы красивые данные, еслиwhile echo $(( RANDOM << 17 | RANDOM << 2 | RANDOM >> 13 )); do :; done | perl -ne 'print pack "I>"' > out
некоторое время запускаете , а затем изучаете содержимоеout
с помощью шестнадцатеричного редактора? (Или это смотреть , однако еще вам нравится.) Я получаю все нули, аRANDOM
не преступник: Я получаю все нули , когда я заменяю$(( RANDOM << 17 | RANDOM << 2 | RANDOM >> 13 ))
с100
тоже.Скажем, у вас есть файл
notifications.txt
. Нам нужно посчитать общее количество строк, чтобы определить диапазон случайного генератора:Давайте напишем в переменную:
Теперь для генерации числа от
0
до$LINE
мы будем использоватьRANDOM
переменную.Давайте запишем это в переменную:
Теперь нам нужно только напечатать этот номер строки:
О СЛУЧАЙНОМ:
Убедитесь, что в вашем файле меньше 32767 номеров строк. Смотрите это , если вам нужно больше генератор случайных чисел , который работает из коробки.
Пример:
источник
LINES=$(wc -l < file.txt); R_LINE=$((RANDOM % LINES)); sed -n "${R_LINE}p" file.txt
$RANDOM % n
может исказить ваше случайное распределение, даже если с$RANDOM
ним все в порядке% n
случайное число.Вот скрипт Python, который выбирает случайную строку из входных файлов или стандартного ввода:
Алгоритм имеет O (n) -время, O (1) -пространство. Он работает для файлов размером более 32767 строк. Он не загружает входные файлы в память. Он читает каждую входную строку ровно один раз, т. Е. Вы можете передать в нее произвольно большой (но конечный) контент. Вот объяснение алгоритма .
источник
Я впечатлен работой, которую проделали Malte Skoruppa и другие, но вот гораздо более простой способ сделать это:
Как уже отмечалось, $ RANDOM не является случайным. Однако ограничение размера файла в 32767 строк преодолевается путем объединения $ RANDOM вместе при необходимости.
источник