使用 Makefile 遍历目录
Traversing a directory using Makefile
我正在使用 makefile 遍历目录,将文件名存储在变量中,使用正则表达式提取文件号并打印文件号。
下面是我使用的代码块:
1. set -e ;\
2. for file in $$(MY_HOME)/mydir/python_files/ ;\
3. do \
4. string =$${file} ;\
5. [[ $$string =~ .*clause([0-9]*).py ]] ;\
6. file_num=$${BASH_REMATCH[1]} ; \
7. python $$(My_Home)/base_py_<file_num>.py ;\
8. done ;\
第 7 行是 makefile 中我想包含在 for 循环中的命令。我想要上面 < file_num > 占位符(第 7 行)中的实际 file_num。我怎样才能做同样的事情。是否有相同的替代方法?
提前致谢
我会采用本机 make
方法而不是循环使用 bash,如下所示:
$ cat Makefile
MY_HOME := myhome
CLAUSE_FILES_DIR := $(MY_HOME)/mydir/python_files
clause_files := $(wildcard $(CLAUSE_FILES_DIR)/*clause*.py)
clause_numbers := $(foreach clause_file,$(notdir $(clause_files:.py=)), \
$(lastword $(subst clause, ,$(clause_file))))
.PHONY: execute-clause-%
execute-clause-%: $(MY_HOME)/base_py_%.py $(CLAUSE_FILES_DIR)/*clause%.py
echo python $<
all: $(addprefix execute-clause-,$(clause_numbers))
clause_files
将保持所有现有文件与模式匹配。 clause_numbers
将通过剥离扩展名和目录来处理文件名,然后在 子句 上拆分,只得到 子句 和扩展名之间的部分。
execute-clause-%
是 运行 的通用规则,基于特定 base_py_*.py 脚本和匹配的 子句 文件。如果一个或另一个不存在,则规则将不是 运行.
最后 all
规则执行所有现有的子句。由于每个处理都是由单独的规则完成的,因此所有这些处理都可以通过 运行ning make -j
.
并行执行
示例输出:
## Preparation stage
$ mkdir -p myhome/mydir/python_files
$ for i in `seq 1 5`; do touch myhome/base_py_$i.py; done
$ for i in `seq 1 5`; do touch myhome/mydir/python_files/${RANDOM}_clause$i.py; done
$ touch myhome/mydir/python_files/foo.py # Just to show it does not match
$ touch myhome/base_py_100.py # To demonstrate missing clause file
$ ls -R myhome/
myhome/:
base_py_1.py base_py_100.py base_py_2.py base_py_3.py base_py_4.py base_py_5.py mydir
myhome/mydir:
python_files
myhome/mydir/python_files:
14363_clause1.py 31198_clause2.py 4514_clause5.py 4767_clause4.py 7812_clause3.py foo.py
## Execution
$ make -s
python myhome/base_py_3.py
python myhome/base_py_2.py
python myhome/base_py_5.py
python myhome/base_py_4.py
python myhome/base_py_1.py
请注意,foo.py
和 base_py_100.py
都没有导致 运行 违反规则。
我正在使用 makefile 遍历目录,将文件名存储在变量中,使用正则表达式提取文件号并打印文件号。
下面是我使用的代码块:
1. set -e ;\
2. for file in $$(MY_HOME)/mydir/python_files/ ;\
3. do \
4. string =$${file} ;\
5. [[ $$string =~ .*clause([0-9]*).py ]] ;\
6. file_num=$${BASH_REMATCH[1]} ; \
7. python $$(My_Home)/base_py_<file_num>.py ;\
8. done ;\
第 7 行是 makefile 中我想包含在 for 循环中的命令。我想要上面 < file_num > 占位符(第 7 行)中的实际 file_num。我怎样才能做同样的事情。是否有相同的替代方法?
提前致谢
我会采用本机 make
方法而不是循环使用 bash,如下所示:
$ cat Makefile
MY_HOME := myhome
CLAUSE_FILES_DIR := $(MY_HOME)/mydir/python_files
clause_files := $(wildcard $(CLAUSE_FILES_DIR)/*clause*.py)
clause_numbers := $(foreach clause_file,$(notdir $(clause_files:.py=)), \
$(lastword $(subst clause, ,$(clause_file))))
.PHONY: execute-clause-%
execute-clause-%: $(MY_HOME)/base_py_%.py $(CLAUSE_FILES_DIR)/*clause%.py
echo python $<
all: $(addprefix execute-clause-,$(clause_numbers))
clause_files
将保持所有现有文件与模式匹配。 clause_numbers
将通过剥离扩展名和目录来处理文件名,然后在 子句 上拆分,只得到 子句 和扩展名之间的部分。
execute-clause-%
是 运行 的通用规则,基于特定 base_py_*.py 脚本和匹配的 子句 文件。如果一个或另一个不存在,则规则将不是 运行.
最后 all
规则执行所有现有的子句。由于每个处理都是由单独的规则完成的,因此所有这些处理都可以通过 运行ning make -j
.
示例输出:
## Preparation stage
$ mkdir -p myhome/mydir/python_files
$ for i in `seq 1 5`; do touch myhome/base_py_$i.py; done
$ for i in `seq 1 5`; do touch myhome/mydir/python_files/${RANDOM}_clause$i.py; done
$ touch myhome/mydir/python_files/foo.py # Just to show it does not match
$ touch myhome/base_py_100.py # To demonstrate missing clause file
$ ls -R myhome/
myhome/:
base_py_1.py base_py_100.py base_py_2.py base_py_3.py base_py_4.py base_py_5.py mydir
myhome/mydir:
python_files
myhome/mydir/python_files:
14363_clause1.py 31198_clause2.py 4514_clause5.py 4767_clause4.py 7812_clause3.py foo.py
## Execution
$ make -s
python myhome/base_py_3.py
python myhome/base_py_2.py
python myhome/base_py_5.py
python myhome/base_py_4.py
python myhome/base_py_1.py
请注意,foo.py
和 base_py_100.py
都没有导致 运行 违反规则。