WedX - журнал о программировании и компьютерных науках

Извлечение x случайных значений из массива bash

У меня есть массив в Bash, скажем, он содержит числа {1, 2, 3, 4, 5}. Я хочу извлечь некоторые из этих чисел случайным образом, чтобы одно и то же число не извлекалось дважды.

По сути, если бы я хотел извлечь 3 числа из массива, мне нужны такие результаты, как: {3, 4, 1} или {5, 2, 4}, а не {1, 1, 3} или {2, 5, 2} .

Я пробовал удалять элементы по мере их извлечения, но всегда что-то путалось. Кто-нибудь может помочь?

28.07.2011

  • перетасовать массив, а затем выбрать n первых элементов? Google для массива bash shuffle находит некоторые подсказки, например stackoverflow.com/questions/5533569/ 28.07.2011

Ответы:


1

Решил написать ответ, так как нашел вариант --input-range к shuf, который оказался удобным:

N=3
ARRAY=( zero one two three four five )

for index in $(shuf --input-range=0-$(( ${#ARRAY[*]} - 1 )) -n ${N})
do
    echo ${ARRAY[$index]}
done
28.07.2011

2

Как насчет этого:

for i in {1..10}; do
    echo $i
done | shuf 

Это вернет все числа. Если вам нужна только конкретная сумма, сделайте следующее:

numbers=5    
for i in {1..10}; do
    echo $i
done | shuf | head -$numbers 

И если вы хотите изменить числа, просто измените переменную {1..10} на то, что хотите.

28.07.2011
  • Ваш код абсолютно работает, но если вы делаете shuf --input-range 1-10, вам не нужен цикл for для отображения набора индексов массива. 29.07.2011

  • 3

    Еще один синтаксис, все еще использующий shuf и сохраняющий элементы с пробелами:

    N=3
    ARRAY=( one "two = 2" "3 is three" 4 five )
    
    
    for el in "${ARRAY[@]}"; do echo $el; done | shuf | head -$N
    
    23.04.2014

    4

    Это может сработать для вас, если вы хотите настоящее чистое решение для bash.

    takeNrandom() {
    # This function takes n+1 parameters: k a1 a2 ... an
    # Where k in 0..n
    # This function sets the global variable _takeNrandom_out as an array that
    # consists of k elements chosen at random among a1 a2 ... an with no repetition
        local k=$1 i
        _takeNrandom_out=()
        shift
        while((k-->0 && $#)); do
            ((i=RANDOM%$#+1))
            _takeNrandom_out+=( "${!i}" )
            set -- "${@:1:i-1}" "${@:i+1}"
        done
    }
    

    Попытайся:

    $ array=( $'a field with\na newline' 'a second field' 'and a third one' 42 )
    $ takeNrandom 2 "${array[@]}"
    $ declare -p _takeNrandom_out
    declare -a _takeNrandom_out='([0]="a second field" [1]="a field with
    a newline" [2]="and a third one")'
    

    (новая строка действительно сохраняется в поле массива).

    Это использует позиционные параметры и использует set -- "${@:1:i-1}" "${@:i+1}" для удаления i-го позиционного параметра. Мы также использовали косвенное расширение в строке _takeNrandom_out+=( "${!i}" ), чтобы иметь доступ к i-му позиционному параметру.

    Примечание. Здесь используется переменная RANDOM по модулю, поэтому распределение не совсем однородно. Это должно быть хорошо для массивов с небольшим количеством полей. В любом случае, если у вас огромный массив, вам, вероятно, не следует использовать Bash в первую очередь!

    23.04.2014

    5

    очень простой 'oneliner' мне нравится:

    shuf -e ${POOL[@]} -n3
    

    даст вам 3 случайных элемента из вашего массива $POOL

    ex:

    #~ POOL=(a b c d e)
    #~ shuf -e ${POOL[@]} -n3
    
    d
    e
    a
    
    31.10.2019
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]