Это возможно, используя JSON API Homebrew, а также некоторые jq
волхвы c (brew install jq
).
1- Предполагая, что ни один из ваших .app
имена файлов содержат новую строку (очень маловероятно), вы можете получить список в виде JSON массива с командой, объединяющей ls
и jq
. Однако, поскольку мы будем использовать этот список для поиска, лучше вместо этого создать объект:
ls /Applications | \grep '\.app$' | jq -Rsc 'split("\n")[:-1]|map({(.):1})|add'
Это создает объект с каждым приложением в качестве ключа и 1
в качестве значения (значение не имеет важность здесь). Он выводит что-то вроде:
{"1Password 7.app":1,"Amphetamine.app":1, "Firefox.app":1, …}
2 - Вы можете перечислить все 3500+ устанавливаемых бочек, используя brew search --casks
. Чтобы получить JSON, описывающий одну или несколько бочек, включая .app
, которые они устанавливают, вы можете использовать brew cask info --json=v1 <cask> …
.
Комбинируя эти два, мы можем получить огромное JSON описание всех устанавливаемых бочек с помощью:
brew search --casks | xargs brew cask info --json=v1 > allcasks.json
Эта команда занимает ~ 10 секунд на моем компьютере, поэтому сохранение ее в файл - хорошая идея.
3 - Теперь мы можем отфильтровать этот список для извлечения только бочки, которые устанавливают .app
s из нашего предыдущего списка:
cat allcasks.json | jq -r --argjson list '{…the list…}' '.[]|(.artifacts|map(.[]?|select(type=="string")|select(in($list)))|first) as $app|select($app)|"\(.token): \($app)"'
Замените {…the list…}
на объект, который мы создали ранее.
Это печатает что-то вроде:
1password: 1Password 7.app
firefox: Firefox.app
google-chrome: Google Chrome.app
…
Если вы чувствуете себя авантюрным, вот одна строка, которая выполняет все эти команды одновременно:
brew search --casks|xargs brew cask info --json=v1|jq -r --argjson l "$(ls /Applications|\grep '\.app$'|jq -Rsc 'split("\n")[:-1]|map({(.):1})|add')" '.[]|(.artifacts|map(.[]?|select(type=="string")|select(in($l)))|first) as $a|select($a)|"\(.token): \($a)"'
Разбивка команды jq
:
.[] # flatten the list
| # then for each element:
( # take its artifacts
.artifacts
# then for each one of them
| map(
# take only arrays
.[]?
# select their string elements
| select(type=="string")
# that are also in the list
| select(in($list)
)
)
# take the first matching artifact
| first)
# and store it in $app
as $app
# then take only the elements with a non-empty $app
| select($app)
# and print their name (.token) and the app ($app)
|"\(.token): \($app)"