如何让Make工具批量处理多种格式的音频文件
问题
我写了个Makefile用来批量把MP3转成文本,本来用得好好的:
%.txt : %.mp3 $(WS) $(FLAGS) ./$<
但我的工具其实支持直接处理WAV、M4A这些格式,不想浪费时间转格式。试了下面的写法却完全没用:
%.txt : %.mp3 %.wav %.m4a $(WS) $(FLAGS) ./$<
为啥原来的写法不行?
你写的这个多依赖规则,Make会理解成:必须同时存在同名的mp3、wav、m4a三个文件,才会触发生成对应的txt。这显然和你要的“只要有其中一种格式就处理”完全相反。
解决办法
用foreach加eval动态生成每个音频格式对应的模式规则,再自动收集所有目标文件,就能批量处理多种格式了。完整的Makefile如下:
.SUFFIXES : .txt .m4a .mp3 .wav SOURCES := $(wildcard *.m4a) TEXT := $(wildcard *.txt) OBJ := $(subst m4a,txt,$(SOURCES)) WS = whisper FLAGS = --device cuda:1 --model small .PHONY: test clean imported # 给每个音频格式单独生成转txt的规则 define template = %.txt: %.$(1) $(WS) $(FLAGS) $$< endef $(foreach extension,mp3 wav m4a,$(eval $(call template,$(extension)))) # 把所有支持的音频文件都找出来,生成对应的txt目标 BIN := $(wildcard *.mp3 *.wav *.m4a) TXT := $(addsuffix .txt,$(basename $(BIN))) all: $(TXT) clean : rm *~ *.json *.srt *.tsv *.vtt split: $(TEXT) awk -v RS="." -v ORS=".\n" 'NR%70==1 {file = sprintf("./tmp/$(patsubst %.txt,%, $< )%04d.txt", NR)} {print > file}' $< imported: mv odt/*.odt odt/imported/ test: $(SOURCES) @echo $(OBJ) @echo PREREQUISITES: $^
核心逻辑说明
- 动态规则生成:
foreach遍历mp3、wav、m4a三个格式,用eval和模板为每个格式创建独立的%.txt: %.xxx规则,这样只要有同名的xxx文件,就会自动触发转txt的操作。 - 目标自动收集:用
wildcard捞取所有支持格式的音频文件,再通过basename和addsuffix把每个音频文件名转换成对应的txt文件名,让all目标自动处理所有音频。
内容的提问来源于stack exchange,提问作者Rick Dearman
相关产品推荐
相关产品推荐

