Makefile для БОЛЬШОГО количества файлов
Я никогда раньше не писал Makefiles, но подозреваю, что это будет полезно в моей ситуации. У меня есть набор текстовых файлов, которые мне нужно предварительно обработать, чтобы извлечь функции для машинного обучения. Структура каталогов может быть такой:
/
+---Makefile
+---/corpus
| +-- a.txt
| +-- b.txt
| +-- ...
|
+---/wordcounts
| +-- a.wordcount
| +-- b.wordcount
| +-- ...
|
+---/lettercounts
| +-- a.lettercount
| +-- b.lettercount
| +-- ...
|
...
Файлы в /wordcounts
а также /lettercounts
генерируются из файлов в /corpus
, Только для файла a.txt
, Я могу написать make
зависимости как это:
all: wordcounts/a.wordcount lettercounts/a.lettercount
wordcounts/a.wordcount: corpus/a.txt
cat corpus/a.txt | wc -w > wordcounts/a.wordcount
lettercounts/a.lettercount: corpus/a.txt
cat corpus/a.txt | wc -m > lettercounts/a.lettercount
Тем не менее, с тысячами файлов в \corpus
этот Makefile станет чрезвычайно длинным. Я хочу написать Makefile, который будет адаптироваться к любым файлам в \corpus
, Идея в том, что независимо от того, сколько файлов я положил /corpus
, Makefile автоматически создаст все остальные файлы. Как я могу это сделать? Это что automake
для?
Фон В настоящее время я использую несколько скриптов для генерации больших csv
файлы, и запуск всех сценариев для всего корпуса занимает пару часов. Мне нужно реструктурировать так, чтобы изменения в одном файле не требовали повторной обработки всего корпуса. Я приветствую любые предложения о том, как настроить проект более эффективно, если то, что я предлагаю, не является идеальным.
1 ответ
Вот один из способов сделать это
corpora := $(wildcard corpus/*.txt)
wordcounts := $(corpora:corpus/%.txt=wordcounts/%.wordcount)
lettercounts := $(corpora:corpus/%.txt=lettercounts/%.lettercount)
.PHONY: all
all: $(wordcounts) $(lettercounts)
$(wordcounts): wcflags += -w
$(wordcounts): wordcounts/%.wordcount: corpus/%.txt
$(lettercounts): wcflags += -m
$(lettercounts): lettercounts/%.lettercount: corpus/%.txt
$(wordcounts) $(lettercounts):
cat $< | wc $(wcflags) > $@
Бежать make
с -r
флаг, чтобы отключить встроенные правила для максимальной производительности.