Embaralhar argumentos de nome de arquivo em zsh

Embaralhar argumentos de nome de arquivo em zsh

Suponha que o aplicativo só possa abrir arquivos por meio de argumentos de linha de comando. Como eu faria para randomizar uma lista de nomes/caminhos de arquivos para fazer isso?

Achei que isso deveria ser bastante fácil, mas aparentemente os espaços tornam tudo mais complicado do que deveria ser.


Um exemplo:

a.mp3
b.mp3
com espaço.mp3

Quando tento, $(ls | shuf)o espaço não escapa, produzindo algo como with space.mp3 b.mp3 a.mp3.

Usar a opção quote -Qtambém não ajuda porque a substituição do comando escapa das aspas, resultando no seguinte:\"with space.mp3\" \"a.mp3\" \"b.mp3\"

Da mesma forma, as fugas de -bget escaped também:with\\ space.mp3 a.mp3 b.mp3

Algo como find's -exec <application> {} \+sem a descoberta seria perfeito ...

Responder1

Aqui está uma variante somente zsh, eliminando lstambém shuf:

mplayer *.mp3(oe:REPLY=\$RANDOM:)

O Qualificador Glob oexecuta ( e) o código entre dois pontos ( :). O código, por sua vez, atribui a cada arquivo um número pseudoaleatório $RANDOM, resultando em uma ordem arbitrária.

Para obscurecer um pouco mais o comando, mas principalmente para salvar as teclas digitadas, você pode definir uma função shell s:

s() { REPLY=$RANDOM }
mplayer *.mp3(oe:s:)

Ou, melhor ainda, defina uma ligação de tecla, por exemplo, CTRL+Rpara a parte aleatória:

bindkey -s '^R' '(oe:REPLY=\\$RANDOM:)^M'

Agora, digite apenas mplayer *.mp3seguido de CTRL+R, e a (oe:REPLY=\$RANDOM:)parte será anexada e a linha de comando executada imediatamente ( ^M).

Responder2

Você não precisa lsde nada. Tentar

mplayer "${(f)$(shuf -e *.mp3)}"

O problema lsé que muitas vezes ele recebe um alias semelhante ls --color=alwayse, nesse caso, imprime caracteres invisíveis que não são reconhecidos corretamente por outros programas ( shufneste exemplo).

Responder3

Acho que finalmente descobri um método:${(f)"$(ls | shuf)"}

Discriminação:

ls | shuf: Embaralhe os arquivos/diretórios conforme o esperado.
"$(...)": as aspas mantêm a saída como está, incluindo novas linhas.
${(f)...}: Divide o resultado da expansão em novas linhas, produzindo uma matriz de nomes de arquivos/diretórios.


"${(f)$(ls | shuf)}"funciona também, ${(f)$(ls | shuf)}não funciona.

informação relacionada