【问题标题】:Traversing a directory using Makefile使用 Makefile 遍历目录
【发布时间】:2021-07-29 10:21:18
【问题描述】:

我正在使用 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 行是我想要包含在 for 循环中的 makefile 中的命令。我想要上面 占位符(第 7 行)中的实际 file_num。我怎么能这样做。是否有任何替代方法?

提前致谢

【问题讨论】:

  • 您是否可以编写一些 Python 脚本来完成这项工作? Makefile 可以运行 Python 脚本(某些 Python 脚本可以运行 make)。阅读GNU makePython 的文档
  • 另请阅读Recursive make considered harmful。如果允许,请考虑使用GNU findutils 或使用nftw(3) 和其他syscalls(2) 编写您的C 程序。另见Advanced Linux ProgrammingGNU bash 的文档
  • 我是这方面的初学者。只是想澄清一下,我们可以像上面所示的那样在 for 循环中运行 makefile 的一些命令吗?
  • 也许您想要一个更具可读性的软件...您可以编写的代码并不总是您应该编写的代码。您可能会从 现有 开源软件中获得灵感,例如 FLTKRefPerSysninja 等...另请参阅 linuxfromscratch.org - 我认为您的 Makefile 不是解决问题的最佳工具
  • 另外,请提供一些minimal reproducible example - 你的代码块不是一个。您可以使用 GNU autoconfninja 吗?您是否允许阅读他们的文档,下载他们的源代码并进行研究(他们都是open source software...)。当然,几种替代方法可以解决您的问题(不清楚)

标签: linux bash unix makefile automation


【解决方案1】:

我会采用原生的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 将通过剥离扩展名和目录来处理文件名,然后在 clause 上拆分以仅获取 clause 和扩展名之间的部分。

execute-clause-% 是基于特定 base_py_*.py 脚本和匹配 clause 文件的存在运行的通用规则。如果其中一个不存在,则不会运行该规则。

最后all 规则执行所有现有子句。而且由于每个处理都由单独的规则完成,所有这些都可以通过运行 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.pybase_py_100.py 都不会导致规则运行。

【讨论】:

  • 非常感谢@rapsy。这确实对我帮助很大。能否请您提供您的电子邮件,以便我与您联系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
相关资源
最近更新 更多