Возврат рандомизированных элементов из glob match

Вы можете заключить путь в одинарные кавычки, чтобы $ не расширялся.

4
08.11.2019, 17:51
1 ответ

Использовать ключ случайной сортировки(квалификатор globoe)::

*(Noe\''REPLY=$RANDOM,$RANDOM'\')

Пояснение:

    За
  • oeследует разделитель из одного символа -, фрагмент кода и еще один разделитель. Кусок кода не может содержать разделитель. Специальные символы необходимо экранировать, чтобы они не анализировались при анализе самих квалификаторов glob.
  • Я использую 'в качестве символа-разделителя (с обратной косой чертой, потому что его нужно экранировать ), и я заключаю код в 'для защиты специальных символов, которые могут присутствовать. Таким образом, я могу написать произвольный код, если он не содержит '.
  • Этот фрагмент кода выполняется для каждого совпадающего имени файла по очереди.
  • REPLYизначально устанавливается на имя файла, и все, что устанавливает код REPLY, используется в качестве ключа сортировки ).

Для случайной выборки $nэлементов добавьте квалификатор […]:

*(Noe\''REPLY=$RANDOM,$RANDOM'\'[1,$n])

Иногда некоторые элементы получают один и тот же ключ сортировки, поэтому все перестановки неравновероятны, с небольшим предпочтением сохранять любые результаты применения функции сортировки к списку в порядке каталога¹, но смещение невелико. Я использую $RANDOM,$RANDOMв качестве ключа сортировки, а не $RANDOM, чтобы уменьшить смещение:$RANDOM— это 15-битное -число, и смещение будет заметно, когда количество файлов приблизится к 2^15.

Обратите внимание, что $RANDOMдостаточно хорош для выборки, если небольшое смещение не вызывает беспокойства. Он не подходит для всего, что связано с безопасностью. Если вам нужна безопасная случайная перестановка, используйте GNU coreutils shuf. (Если в вашей любимой ОС отсутствует нативная shufи вы по какой-то причине не хотите устанавливать GNU coreutils, вы можете вместо этого попробовать повторную реализацию от ibara.)

securely_permuted=("${(0)$(printf '%s\0' *(N) | shuf -z))}")

или более простая версия, которая может привести к ограничению длины командной строки:

securely_permuted=("${(0)$(shuf -z -- *(N)))}")

¹ Экспериментально сорт стабилен (e.g. *(omoe\''REPLY=1'\')эквивалентно *(om),но порядок только из *(oe\''REPLY=1'\')не соответствует *(oN). В любом случае это небольшой перекос в пользу какого-то определенного порядка.

6
27.01.2020, 20:53

Теги

Похожие вопросы