Andando pelos arquivos no diretório aleatoriamente

6

Como alterar for track in *.mp3; do para que todos os arquivos .mp3 no diretório atual sejam percorridos, mas de forma aleatória?

    
por runbehind 20.05.2013 / 20:37

3 respostas

9

Para referência, em zsh , você pode afetar os globs de ordem que são expandidos com o qualificador o globbing. Por exemplo, *.mp3(om) classifica por tempo de modificação. Você pode definir sua própria ordem de classificação com funções.

Com *.mp3(o+foo) , os arquivos são classificados, não com base em seu nome, mas no valor que a função foo retorna na variável $REPLY de um determinado nome de arquivo (e foo recebe o nome do arquivo em $REPLY também). Então, por exemplo com:

rand() REPLY=$RANDOM

for i in *.mp3(o+rand); do
  echo "$i"
done

Você recebe um pedido aleatório.

POSIXly, e se você não quiser fazer suposições sobre quais nomes de arquivos podem conter, você pode fazer algo como:

shuffle() {
  awk -v q="'" 'BEGIN {
    printf "set --"
    for (i=1; i < ARGC; i++) {
      r=int(rand()*(ARGC-1)+1);x=ARGV[i];ARGV[i]=ARGV[r];ARGV[r]=x
    }
    for (i=1;i<ARGC;i++) {
      a=ARGV[i];gsub(q, q "\" q q, a);printf " %s", q a q
    }
    print "";exit}' "$@"
}
eval "$(shuffle *.mp3)"
for i do
  echo "$i"
done
    
por 20.05.2013 / 21:29
5

Você pode usar o comando shuf para embaralhar as linhas para você. Apenas backtick um comando list onde você tem * .mp3 e canaliza para shuf , como:

#!/bin/bash -
SAVEIFS=$IFS
IFS=$'\n'; set -f
for i in 'find . -maxdepth 1 -iname '*.mp3' -type f | shuf'
do
    echo "$i"
done
IFS=$SAVEIFS; set +f

O exemplo acima assume o GNU find e os nomes dos arquivos não contêm caracteres de nova linha.

    
por 20.05.2013 / 20:55
2

find . -name \*.mp3 -maxdepth 1 -print0 | shuf -z | while IFS= read -d '' -r l; do printf %s\n "$l"; done

  • -maxdepth, -print0, shuf e read -d não são definidos pelo POSIX. O shuf faz parte do coreutils.
  • leia os caracteres das faixas no IFS desde o início e o final das linhas. -r desativa a interpretação de barras invertidas. -d '' é o mesmo que -d $'printf %s\n *.mp3 | shuf | while read l; do printf %s\n "$l"; done' .

Ou se os caminhos não contiverem alimentação de linha ou barras invertidas e não começarem nem terminarem com caracteres no IFS:

%code%

    
por 21.05.2013 / 16:14