открыть случайный файл в OSX с помощью командной строки

открыть случайный файл в OSX с помощью командной строки

Я хотел бы открыть случайно выбранный файл через терминал. Я нашел shuf, который, похоже, является как раз той утилитой, которая мне нужна, хотя я не могу придумать, как сделать команду, с которой я работаю, рекурсивной.

Изначально я использовал open $(ls | gshuf -n1), что отлично работает, если у меня плоская структура каталогов. Как мне сделать так, чтобы это рекурсивно проходило в любое количество подкаталогов и отфильтровывало файлы вроде .DS_Storeи папки?

решение1

Правильный инструмент — find. Он работает рекурсивно, это решает вашу главную проблему. Вы можете исключить различные шаблоны, если знаете как.

Базовое использование будет таким:

open "$(find . -type f | shuf -n1)"

Переводы строк в именах файлов нарушат это. Ваши инструменты могут поддерживать или не поддерживать не-POSIX-опции, которые позволяют передавать данные с NUL-терминатором. Этот фрагмент работает в моем Debian:

find . -type f -print0 | shuf -z -n1

хотя если вы вставите его в $(…), конечные переносы строк (если таковые имеются) все равно будут удалены.

Чтобы исключить имена, можно использовать синтаксис вроде ! -name .DS_Store, но чтобы исключить целые подкаталоги, нужно-prune. Есть подводные камни:

  • Порядок операндов имеет значение, например, -pruneдля каталога он должен быть перед -type f, -print/ -print0обычно находится в конце.
  • Логическое «или» ( -o)часто требуются скобкии это не так интуитивно понятно, как вам бы хотелось.
  • Пропуск -print/ -print0может дать вам больше результатов, чем вы ожидаете. При сложной логике хорошо явно включать -print/ -print0.

Изучите man 1 find, чтобы узнать больше. Это рабочий пример, который исключает два каталога и два шаблона имен:

find . \( -name dir1 -o -name "dir 2" \) -prune -o -type f ! \( -name "*.txt" -o -name "echo*" \) -print

Поскольку вам нужно $(…), и я сказал вам, правильно цитировать, вы должны знать, что кавычки внутри $(…)разбираются отдельно. Например, это правильно цитируется:

open "$(find . -type f ! -name "not this file" | shuf -n1)"

(сравниватьэтот ответ, причуда 2).

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