Прошло много времени с тех пор, как я использовал make
, так что терпите меня ...
У меня есть каталог flac
, содержащий файлы .FLAC. У меня есть соответствующий каталог, mp3
содержащий файлы MP3. Если файл FLAC новее, чем соответствующий файл MP3 (или соответствующий файл MP3 не существует), я хочу запустить несколько команд для преобразования файла FLAC в файл MP3 и скопировать теги.
Кикер: мне нужно flac
рекурсивно искать в каталоге и создавать в нем соответствующие подкаталоги mp3
. Каталоги и файлы могут иметь пробелы в именах и имеют имена в кодировке UTF-8.
И хочу использовать make
для этого.
make
он ближе к реализации, чем голыйbash
.sh
сценарий, который просматривает список файлов flac (find | while read flacname
), создаетmp3name
из него, запускает "mkdir -p"dirname "$mp3name"
и затемif [ "$flacfile" -nt "$mp3file"]
конвертирует"$flacname"
в , на"$mp3name"
самом деле не волшебство. Единственная функция, которую вы фактически теряете по сравнению сmake
базовым решением, - это возможность запускатьN
процессы преобразования файлов параллельно сmake -jN
.make
и наличие пробелов в именах файлов - противоречивые требования. Используйте инструмент, соответствующий проблемной области.Ответы:
Я бы попробовал что-нибудь в этом роде
Несколько замечаний для
make
начинающих:@
перед командами предотвращаетmake
печать команды до ее фактического выполнения.$(@D)
является частью каталога имени целевого файла ($@
)Даже если это должно обрабатывать все символы UTF-8 и прочее, он не будет работать с пробелами в именах файлов или каталогов, поскольку
make
использует пробелы для разделения вещей в make-файлах, и я не знаю, как это обойти. Боюсь, у вас останется только сценарий оболочки: - /источник
vpath
. Должен изучить это на днях.find
получить имена рекурсивно ...make -jN
. ДляN
использования количества преобразований, которыеmake
должны выполняться параллельно. Внимание: запускmake -j
безN
символа запускает все процессы преобразования одновременно, что может быть эквивалентно форк-бомбе..PHONY: all
Строка сообщает программе make, что рецепт дляall
цели должен быть выполнен, даже если есть файл с именемall
новее, чем все файлы$(MP3_FILES)
.Вы можете определить свою собственную рекурсивную функцию с подстановочными знаками следующим образом:
Первый параметр (
$1
) - это список каталогов, а второй ($2
) - список шаблонов, которым вы хотите сопоставить.Примеры:
Чтобы найти все файлы C в текущем каталоге:
Для того, чтобы найти все
.c
и.h
файлыsrc
:Эта функция основана на реализации из этой статьи с некоторыми улучшениями.
источник
make
это яма смолы Тьюринга (см. Здесь: yosefk.com/blog/fun-at-the-turing-tar-pit.html ). Это даже не так сложно, но нужно прочитать это: gnu.org/software/make/manual/html_node/Call-Function.html, а затем «понять повторение». ВАМ приходилось писать это дословно, рекурсивно; это не повседневное понимание «автоматически включать файлы из подкаталогов». Это реальное ВОЗНИКНОВЕНИЕ. Но помните - «Чтобы понять повторение, вы должны понять повторение».FWIW, я использовал что-то вроде этого в Makefile :
В приведенном выше примере выполняется поиск в текущем каталоге ( '.' ) Всех «простых файлов» ( '-type f' ) и установка
RECURSIVE_MANIFEST
переменной make для каждого найденного файла. Затем вы можете использовать подстановки шаблонов, чтобы уменьшить этот список, или, альтернативно, предоставить больше аргументов в find, чтобы сузить то, что он возвращает. См. Справочную страницу для поиска .источник
Мое решение основано на приведенном выше,
sed
вместо того,patsubst
чтобы искажать выводfind
И экранировать пробелы.Переход с flac / на ogg /
Предостережения:
источник
Вот сценарий Python, который я быстро взломал, чтобы решить исходную проблему: сохранить сжатую копию музыкальной библиотеки. Сценарий преобразует файлы .m4a (предполагается, что это ALAC) в формат AAC, если файл AAC уже не существует и новее, чем файл ALAC. Файлы MP3 в библиотеке будут связаны, поскольку они уже сжаты.
Просто помните, что при прерывании скрипта ( ctrl-c) останется наполовину преобразованный файл.
Первоначально я также хотел написать Makefile, чтобы справиться с этим, но поскольку он не может обрабатывать пробелы в именах файлов (см. Принятый ответ) и поскольку написание сценария bash гарантированно поставит меня в мир боли, Python это так. Он довольно простой и короткий, поэтому его легко настроить в соответствии с вашими потребностями.
Конечно, это может быть улучшено для параллельного кодирования. Это оставлено читателю в качестве упражнения ;-)
источник
Если вы используете Bash 4.x, вы можете использовать новую опцию подстановки , например:
Такой рекурсивный подстановочный знак может найти все интересующие вас файлы ( .flac , .mp3 и т. Д.). О
источник
**
не сработает, потому что расширенная подстановка - это вещь bash / zsh.