Перетасовать аргументы имени файла в zsh

Перетасовать аргументы имени файла в zsh

Предположим, что приложение может открывать файлы только с помощью аргументов командной строки. Как мне рандомизировать список имен файлов/путей, чтобы добиться этого?

Я думал, что это должно быть довольно просто, но, видимо, пробелы делают задачу более сложной, чем она должна быть.


Пример:

a.mp3
b.mp3
с пробелом.mp3

Когда я пытаюсь, $(ls | shuf)пробел не экранируется, выдавая что-то вроде with space.mp3 b.mp3 a.mp3.

Использование опции кавычек -Qтакже не помогает, поскольку подстановка команды экранирует кавычки, что приводит к следующему:\"with space.mp3\" \"a.mp3\" \"b.mp3\"

Аналогично экранируются и побеги -bget:with\\ space.mp3 a.mp3 b.mp3

Что-то вроде find's -exec <application> {} \+без находки было бы идеально...

решение1

Вот вариант только для zsh, избавляющийся lsкак от , так и от shuf:

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

Glob Qualifier oвыполняет ( e) код между двумя двоеточиями ( :). Код, в свою очередь, присваивает каждому файлу псевдослучайное число $RANDOM, что приводит к произвольному порядку.

Чтобы еще больше запутать команду, а главное — сэкономить нажатия клавиш, можно определить функцию оболочки s:

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

Или, что еще лучше, определите привязку клавиш, например, CTRL+Rдля части перемешивания:

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

Теперь введите только mplayer *.mp3с последующим CTRL+R, и (oe:REPLY=\$RANDOM:)часть будет добавлена, а командная строка немедленно выполнена ( ^M).

решение2

lsТебе вообще не нужно . Попробуй

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

Проблема в lsтом, что он часто ассоциируется с чем-то вроде , ls --color=alwaysи в этом случае печатает невидимые символы, которые не распознаются должным образом другими программами ( shufв этом примере).

решение3

Думаю, я наконец нашел способ:${(f)"$(ls | shuf)"}

Авария:

ls | shuf: Перемешивает файлы/каталоги, как и ожидалось.
"$(...)": Кавычки сохраняют вывод в том виде, в котором он есть, включая новые строки.
${(f)...}: Разбивает результат расширения по новым строкам, создавая массив имен файлов/каталогов.


"${(f)$(ls | shuf)}"работает также, ${(f)$(ls | shuf)}, не работает.

Связанный контент