我正在尝试:
.env
文件,以便make
可以访问它Makefile
中,将.env
的内容读入变量问题是:
make
用来替换我的换行符以解析我的变量的空格。我的正则表达式可以找到正确的起点,但包含.env
文件的其余部分,而不是在要提取的值之后停在空白处。我了解到,当我将文件cat
make
变成变量时,.env
会删除换行符。来自GNU Make docs:
shell函数执行与反引号('`')相同的功能 在大多数shell中执行:它执行命令扩展。这意味着 将shell命令作为参数,并求值到以下命令的输出 命令。 make对结果所做的唯一处理就是转换 每个换行符(或回车符/换行符对)都放在一个空格中。如果 有一个结尾(回车和换行符) 删除。
但是,我无法获得任何正则表达式来提前识别这些空间来提取变量,或者用另一个字符替换这些空间来辅助提取。
示例:
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
我已经尝试了许多其他正则表达式和命令({{1}},用一个我可以在超前定位的字符替换空格,等等),但是没有运气。
我在做什么错?谢谢。
答案 0 :(得分:5)
我没有完全了解发生了什么,但是我认为您想从诸如这样的字符串中提取值
#include <string>
#include <fstream>
#include <sstream>
void loadArrays(std::string address[], double amountDue[], const int SIZE)
{
//Open file for data loading
std::ifstream inputFile("Prog3Input.txt");
std::string line;
for (int i = 0; i < SIZE; i++)
{
std::getline(inputFile, address[i]);
std::getline(inputFile, line);
std::istringstream(line) >> amountDue[i];
}
}
即SSH_CREDENTIALS=path/to/my/key ANOTHER_VAR=somethingelse YET_ANOTHER_VAR=yetanothersomething
的路径。
如果这确实是主要目标,那么您将很少错过它:
正则表达式中的SSH_CREDENTIALS
是 greedy ,因为它尽可能匹配 以便仍然满足正则表达式。 Sicne之后是空格的前瞻,它将与字符串中的最后一个空格匹配。相反,您想用.*
来限制它,所以要使用?
,它匹配以下模式的 first (此处为空格)
.*?
这在我的测试中正常工作。请注意,您可以简单地匹配非空格字符
grep -o -P '(?<=SSH_CREDENTIALS=).*?(?=[[:space:]])'
我看到一个注释掉的grep -o -P '(?<=SSH_CREDENTIALS=)\S+'
代码段,并且Perl被标记了。使用这些工具的正则表达式更简单,无需提前。因此,进入
sed
或者再次可以匹配所有连续的非空格字符
perl -wne'/SSH_CREDENTIALS=(.*?)\s/; print $1'
我认为您不需要换行符。您也可以使用perl -wne'/SSH_CREDENTIALS=(\S+)/; print $1'
。
查看您喜欢的正则表达式资源。在Perl中,这将是教程perlretut和参考文献perlre。
经过澄清,似乎整个目标是将变量定义从另一个文件拉入Makefile。如果文件格式与显示的格式完全相同,则可以直接为included,从而提供这些变量定义。一个简单的例子
文件 .env
SSH_CREDENTIALS=path/to/my/key ANOTHER_VAR=somethingelse
Makefile
[[:space:]]
使用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
与 makefile 一起使用,因此要包含的文件必须满足该格式。
答案 1 :(得分:2)