【问题标题】:Makefile for a LARGE number of files用于大量文件的 Makefile
【发布时间】:2016-03-09 23:58:46
【问题描述】:

我以前从未编写过 Makefile,但我怀疑它对我的情况会有所帮助。我有一个文本文件语料库,需要对其进行预处理以提取机器学习的特征。目录结构可能是这样的:

/
+---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 文件,并且为整个语料库运行所有脚本需要几个小时。我需要重组,以便一个文件中的更改不需要重新处理整个语料库。如果我的建议不理想,我欢迎任何有关如何更有效地设置项目的建议。

【问题讨论】:

    标签: makefile corpus tagged-corpus


    【解决方案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) > $@
    

    使用 -r 标志运行 make 以禁用内置规则以获得最佳性能。

    【讨论】: