首页 > 解决方案 > 如何在 Makefile 中正确编写 for 循环

问题描述

我浏览了一些帖子,但仍然不知道它是如何工作的。

我的要求是:

for i in *.json
do
  file = `echo $i |cut -d _ -f2`
  echo ${file}
  # do the rest tasks
done

如何将上述脚本转换为 Makefile 的目标?

这是我尝试过的

foo: 
    for i in *.json; do      \
       $(eval FILE = $(shell echo $$i |cut -d _ -f2));    \
       echo $(FILE) ;\
    done

但它不起作用

标签: shellmakefile

解决方案


Using $(eval) or $(shell) is ... not even wrong.

foo: 
    for i in *.json; do \
       file=$$(echo "$$i" |cut -d _ -f2); \
       echo "$$file"; \
    done

Notice the quoting of the filename variables, and the absence of spaces around the = assignment operator, and the doubling of any dollar sign in order to pass it through from make to the shell.

However, the shell provides a much better mechanism for this;

foo:
    for i in *.json; do \
        j=$${i#*_}; \
        echo "$${j%%_*}"; \
    done

or perhaps

foo:
    printf '%s\n' *.json \
    | sed 's/[^_]*_\([^_]*\)_.*/\1/'

If you only expect a single underscore, both of these can be further simplified.

Or maybe you are just looking for

makefile_variable := $(foreach x,$(wildcard *.json),$(word 2,$(subst _, ,$x)))

推荐阅读