Com os qualificadores de glob em zsh
um pode classificar os resultados de uma correspondência de padrão de globbing de nome de arquivo de várias maneiras. Por exemplo, o padrão *(om)
corresponderia a todos os nomes não ocultos no diretório atual, ordenados por carimbo de data/hora de modificação.
No entanto, às vezes eu queria ter uma maneira de ter uma ordenação aleatória (por exemplo, para obter uma amostragem aleatória de arquivos). Até onde eu vi, não há qualificador que faça isso diretamente.
Descrição: Como posso obter de volta uma lista aleatória de nomes de caminho de um zsh
padrão de globbing de nome de arquivo?
Use uma chave de classificação aleatória ( qualificador glob
oe
)::Explicação:
oe
é seguido por um delimitador de um caractere, um pedaço de código e outro delimitador. O pedaço de código não pode conter o delimitador. Caracteres especiais precisam ser escapados para que não sejam analisados durante a análise dos próprios qualificadores glob.'
como o caractere delimitador (com uma barra invertida porque precisa ser escapado) e envolvo o código'
para proteger os caracteres especiais que podem estar presentes. Dessa forma, posso escrever código arbitrário, desde que não contenha arquivos'
.REPLY
é inicialmente definido para o nome do arquivo e qualquer que seja o código definidoREPLY
é usado como uma chave de classificação).Para amostrar
$n
elementos aleatoriamente, adicione o[…]
qualificador:Ocasionalmente, alguns elementos obtêm a mesma chave de classificação, portanto, todas as permutações não são igualmente prováveis, com uma ligeira preferência por manter os resultados da aplicação da função de classificação a uma lista na ordem do diretório¹, mas o viés é pequeno. Eu uso
$RANDOM,$RANDOM
como chave de classificação em vez de$RANDOM
reduzir o viés:$RANDOM
é um número de 15 bits e o viés seria perceptível à medida que o número de arquivos se aproxima de 2^15.Observe que isso
$RANDOM
é bom o suficiente para amostragem se o pequeno viés não for uma preocupação. Não é adequado para nada que envolva segurança. Se você quiser uma permutação aleatória segura, use oshuf
. (Se o seu sistema operacional favorito não tiver um nativoshuf
e você não quiser instalar o GNU coreutils por algum motivo, tente a reimplementação do ibara .)ou uma versão mais simples que pode ter um limite de comprimento de linha de comando:
¹ Experimentalmente a ordenação é estável (por exemplo ,
*(omoe\''REPLY=1'\')
é equivalente a*(om)
, mas a ordem de simplesmente*(oe\''REPLY=1'\')
não corresponde a*(oN)
. De qualquer forma, é um pequeno viés a favor de alguma ordem particular.