Я выполнил следующую команду в оболочке для пакетного преобразования файлов .HEIC в файлы .JPG, команда выполнена успешно, однако есть ее часть, которую я не понимаю:
find . -name '*.HEIC' -exec sh -c 'magick convert $1 "${1%.HEIC}.JPG"' _ {} \;
Очевидно, _ {} позволяет назначить результат find на $1, но как? Я не могу найти объяснения ни в Google, ни здесь, и мне не повезло с man find. Вполне возможно, что ответы были здесь, но эти символы не очень удобны для поиска.
Итак, вопрос в том, как _ {} присваивает переменную $1? Можно ли присвоить ему несколько переменных с помощью команды find / или других команд?





Есть две вещи, связанные с тем, как _ {} назначает имя файла $1. Во-первых, вот как работает find-exec: он запускает следующие аргументы (вплоть до экранированного ;) как команду, но с заменой {} на путь к найденному файлу. Таким образом, если он найдет ./somefile.HEIC, он запустит эквивалент команды:
sh -c 'magick convert $1 "${1%.HEIC}.JPG"' _ ./somefile.HEIC
Вторая часть - это команда sh. sh может делать несколько вещей, но если ему задана опция -c, он принимает следующий за ним аргумент (magick convert $1 "${1%.HEIC}.JPG") в качестве командной строки для синтаксического анализа и запуска, что-то вроде небольшого мини-скрипта. Аргументы после этого принимаются как аргументы этого мини-скрипта, начиная с $0. В данном случае это означает, что он запускает мини-сценарий с $0, установленным на _, и $1, установленным на "./somefile.HEIC". Если бы было предоставлено больше аргументов, это были бы $2, $3 и т. д.
Кроме того, если я не ошибаюсь, команда запускает один дочерний / мини-скрипт для каждого файла, возвращенного из find.
@Inian Верно по обоим пунктам. Вы можете использовать $0 для передачи имени файла, но $0 обычно является именем выполняемой программы (скрипта, исполняемого файла и т. д.), И его использование в качестве файла, с которым выполняется операция, может привести к некоторой путанице. ("_" тоже не очень хорошее название программы, но, по крайней мере, оно не вводит в заблуждение.) Что касается запуска мини-скрипта для каждого файла, вот как работает -exec ... \;. Если вы используете -exec ... +, он будет запускать их большими партиями, поэтому имена файлов будут $1, $2, ... ${148} или любые другие. Вы можете это сделать, но тогда вам понадобится цикл обработки в мини-скрипте.
Спасибо, это очень понятно и полезно. Означает ли это, что _ не требуется, и вместо этого я могу просто использовать $ 0? Есть ли польза от использования 1 доллара?