regex - Makefile 变量 - 替换变量中的空格
问题描述
我在尝试着:
- 导出
.env
文件的路径,以便它可以访问make
- 在 my
Makefile
中,将 的内容读.env
入一个变量 - 将内容解析为我将用于构建和部署应用程序的变量
问题是:
make
为了解析我的变量,我似乎找不到一个正则表达式来匹配替换我的换行符的空格。我的正则表达式得到了正确的起点,但包含了.env
文件的其余部分,而不是在我要提取的值之后的空白处停止。
我知道当cat
我将文件放入变量时,会make
去除换行符。来自GNU Make 文档:
shell 函数执行的功能与大多数 shell 中的反引号 ('`') 执行的功能相同:它执行命令扩展。这意味着它将 shell 命令作为参数并计算命令的输出。make 对结果的唯一处理是将每个换行符(或回车/换行符对)转换为单个空格。如果有尾随(回车和)换行符,它将被简单地删除。
但是,我无法让任何正则表达式提前识别这些空格以提取我的变量,或者用另一个字符替换这些空格以帮助提取。
例子:
.env
:
SSH_CREDENTIALS=path/to/my/key
ANOTHER_VAR=somethingelse
YET_ANOTHER_VAR=yetanothersomething
Makefile
:
ENV_FILE_CONTENTS := $(shell cat $(ENV_FILE_PATH) ) # | sed -e 's/[[:space:]]/x/g'
$(info $(ENV_FILE_CONTENTS))
SSH_CREDENTIALS := $(shell echo $(ENV_FILE_CONTENTS) | grep -o -P '(?<=SSH_CREDENTIALS=).*(?=[[:space:]])' )
$(info $(SSH_CREDENTIALS))
SSH_CREDENTIALS := $(shell echo $(ENV_FILE_CONTENTS) | grep -o -P '(?<=SSH_CREDENTIALS=).*(?=\s)' )
$(info $(SSH_CREDENTIALS))
[recipes below]
命令和结果:
$ export ENV_FILE_PATH=./env/.env; make print_env_var
SSH_CREDENTIALS=path/to/my/key ANOTHER_VAR=somethingelse YET_ANOTHER_VAR=yetanothersomething # My .env file without the newlines
path/to/my/key ANOTHER_VAR=somethingelse # Attempt to extract the path to the SSH credentials fails (doesn't recognize whitespace lookahead)
path/to/my/key ANOTHER_VAR=somethingelse # Samething when trying \s instead of [[:space:]]
我尝试了许多其他正则表达式和命令(sed
用我可以在前瞻中定位的字符替换空格等),但没有运气。
我究竟做错了什么?谢谢你。
解决方案
我不完全了解发生了什么,但我认为您想从字符串中提取值,例如
SSH_CREDENTIALS=path/to/my/key ANOTHER_VAR=somethingelse YET_ANOTHER_VAR=yetanothersomething
也就是 的路径SSH_CREDENTIALS
。
如果这确实是主要目标,那么您几乎没有错过它:
正则表达式中的那
.*
是贪婪的,因为它匹配尽可能多的匹配仍然满足正则表达式。Sicne 后跟一个空格的前瞻,它将匹配字符串中的最后一个空格。相反,你想用 , 来限制它?
,所以要使用.*?
它匹配以下模式中的第一个(此处为空格)grep -o -P '(?<=SSH_CREDENTIALS=).*?(?=[[:space:]])'
这在我的测试中正常工作。请注意,您可以简单地匹配非空格字符
grep -o -P '(?<=SSH_CREDENTIALS=)\S+'
我看到一个注释掉的
sed
片段并且 Perl 被标记。使用这些工具的正则表达式更简单,无需前瞻。所以管道进入perl -wne'/SSH_CREDENTIALS=(.*?)\s/; print $1'
或者,同样,可以匹配所有连续的非空格字符
perl -wne'/SSH_CREDENTIALS=(\S+)/; print $1'
我假设你不需要换行符。您也可以使用
[[:space:]]
.
查看您最喜欢的正则表达式资源。在 Perl 中,这将是教程perlretut和参考perlre。
通过澄清,整个目标似乎是将变量定义从另一个文件拉到 Makefile 中。如果文件的格式完全如图所示,则可以直接包含它,从而提供那些变量定义。一个简单的例子
一个文件.env
SSH_CREDENTIALS=path/to/my/key ANOTHER_VAR=其他
一个Makefile
INCL = /usr/include/boost
include .env
fake:
@echo "a variable: $(INCL)"
@echo "a variable from the included file: $(SSH_CREDENTIALS)"
@echo "another variable from included file: $(ANOTHER_VAR)"
我们得到make
了预期的打印输出。
请记住,它include
与makefile 一起使用,因此要包含的文件必须满足该格式。
推荐阅读
- python-3.x - 如何在 Numpy/MatplotLib 中可视化线性规划(具有任意不等式)的可行区域?
- android - 方法 toList() 没有发出任何东西
- c# - .NETCore 从 2.2.0 到 2.2.3
- laravel - 如何在 laravel 护照中创建登录 api 而无需注册 api 但创建令牌并将其存储在数据库中应该存在于登录 api 中
- microservices - 需要防御带有 CosmosDB 的事件溯源架构的古怪挑战
- reactjs - 在 AWS ampify 中部署时,页面在提交后重定向到 index.html
- javascript - 如何在javascript中创建转换构造函数?
- python - 使用 SQLite 插入命令时解决“无法识别的令牌”错误
- php - 成功连接到数据库后,PhP 代码将无法正确分配
- angular - 无法以正确的路径显示上传的图像