No Bash, como selecionar aleatoriamente um arquivo de uma lista estática?

0

Eu tenho este script bash

while true ; do for i in * ; do cp "$i" ~/slideshow.jpg ; echo $i ; sleep 5 ; done ; done

Como posso randomizar esse processo?

    
por Eukleyv Cardoso 07.07.2016 / 07:28

2 respostas

0

Eu sinto que esta pergunta é uma tarefa de casa. Deixe-me fazer isso por você.

* nesse script provavelmente retornará uma listagem em ordem alfabética de um diretório. Então você poderia interceptar essa listagem e randomizar nesse ponto.

Você também pode carregar o conteúdo do diretório em uma matriz, escolher aleatoriamente um número - mod o tamanho da matriz e, se o resultado estiver vazio, avançar para a frente até atingir uma entrada não vazia. Em seguida, esvazie essa entrada enquanto a consome. Você precisaria de um contador ou algo para saber quantos elementos usou para saber quando consumiu todas as entradas.

Além disso, você pode carregar as entradas em algo como uma lista vinculada e criar uma entrada aleatória nº # para consumir e descartar da estrutura de dados.

Existem muitas outras opções. Mas eu acabei de te dar esboços para 3 abordagens cruas. Claro que não escrevi código para você, mas fiz a parte hard . Você é bem-vindo;)

    
por 07.07.2016 / 07:41
0

O seguinte deve funcionar AFAIK em qualquer sistema POSIX.

Uma lista ordenada aleatória de arquivos pode ser obtida com:

for i in *; do echo "$i"; done |                              \
  awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }' | \
  sort |                                                      \
  cut -f2-

Explicação:

  • for i in *; do echo "$i"; done fornece uma lista de arquivos, um por linha.
  • awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }' adiciona um campo com um número aleatório no intervalo [0,1] para cada linha.
  • sort ordena usando esse número aleatório como índice, portanto, randomizando a lista de arquivos.
  • cut -f2- remove o campo numérico aleatório.

O comando original (com copiar e dormir) pode ser construído como:

for i in $(for i in *; do echo "$i"; done |                              \
             awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }' | \
             sort |                                                      \
             cut -f2-);                                                  \
do                                                                       \
  cp "$i" ~/slideshow.jpg;                                               \
  echo "$i";                                                             \
  sleep 5;                                                               \
done

É claro que você pode remover barras invertidas e novas linhas se você gosta de one-liners;)

    
por 07.07.2016 / 10:18