Mezclar argumentos de nombre de archivo en zsh

Mezclar argumentos de nombre de archivo en zsh

Supongamos que la aplicación solo puede abrir archivos a través de argumentos de línea de comando, ¿cómo haría para aleatorizar una lista de nombres/rutas de archivos para lograr esto?

Pensé que esto debería ser bastante fácil pero aparentemente los espacios lo hacen más complicado de lo que debería ser.


Un ejemplo:

a.mp3
b.mp3
con espacio.mp3

Cuando lo intento, $(ls | shuf)el espacio no se escapa y produce algo como with space.mp3 b.mp3 a.mp3.

Usar la opción de comillas -Qtampoco ayuda porque la sustitución del comando escapa de las comillas, lo que da como resultado lo siguiente:\"with space.mp3\" \"a.mp3\" \"b.mp3\"

De manera similar, los escapes de -bget escaparon también:with\\ space.mp3 a.mp3 b.mp3

Algo como find's -exec <application> {} \+sin el hallazgo sería perfecto...

Respuesta1

lsAquí hay una variante exclusiva de zsh, que también elimina shuf:

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

El Glob Qualifier oejecuta ( e) el código entre ambos dos puntos ( :). El código, a su vez, asigna a cada archivo un número pseudoaleatorio $RANDOM, lo que da como resultado un orden arbitrario.

Para oscurecer un poco más el comando, pero principalmente para guardar las pulsaciones de teclas, puede definir una función de shell s:

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

O, mejor aún, defina una combinación de teclas, por ejemplo, CTRL+Rpara la parte aleatoria:

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

Ahora, escriba solo mplayer *.mp3seguido de CTRL+R, la (oe:REPLY=\$RANDOM:)parte se agrega y la línea de comando se ejecuta inmediatamente ( ^M).

Respuesta2

No necesitas lsnada. Intentar

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

El problema lses que a menudo tiene un alias ls --color=alwaysy en ese caso imprime caracteres invisibles que otros programas no reconocen correctamente ( shufen este ejemplo).

Respuesta3

Creo que finalmente descubrí un método:${(f)"$(ls | shuf)"}

Descomponer:

ls | shuf: Mezcla archivos/directorios como se esperaba.
"$(...)": Las comillas mantienen el resultado tal como está, incluidas las nuevas líneas.
${(f)...}: Divide el resultado de la expansión en nuevas líneas, generando una matriz de nombres de archivos/directorios.


"${(f)$(ls | shuf)}"funciona también, ${(f)$(ls | shuf)}no.

información relacionada