我有一些模板文件,目前正在使用 envsubst 进行处理,效果很好。
<?php
$config['db_host'] = '${DB_HOST}';
$config['db_port'] = '${DB_PORT}';
$config['url'] = 'http://${WEB_HOST}/${WEB_PATH}';
// Please do NOT change this value
$config['maxSize'] = 25;
我试图找到一种使用 bash 脚本扫描文件并生成需要设置的所有环境变量的列表的方法,这样我就可以将它们转储到 .env 文件中,如下所示:
DB_HOST=
DB_PORT=
WEB_HOST=
WEB_PATH=
我认为 sed 是可能的,但是我在 30 分钟的谷歌搜索后找到的所有示例都是关于如何替换内联变量,而不是关于打印出匹配项。
答案1
您的标准似乎是:匹配${
和之间包含的任意数量的大写字母或下划线}
。
gawk
可以单独使用它,或者grep
可以简化模式匹配部分(但之后需要额外的格式化)。
GNU awk
:
gawk -v 'RS=[$]{' -F '}' '$1 ~ /^[A-Z_]+$/ && !a[$1]++ {printf "%s=\n", $1}' FILE
- GNU awk 可以接受记录分隔符的正则表达式,因此通过分配,它将在模式出现的任何地方
RS=[$]{
将输入拆分为记录FILE
${
- 字段分隔符设置为
}
- 现在可以检查每个记录的第一个字段,看看它是否符合您的其他条件:除了一个或多个[A-Z_]
- 使用
&& !a[$1]++
将删除重复项 =
print 语句在每行末尾添加一个等号- 以匹配您所需的输出- 另请注意:文件的第一部分将始终被算作第一个记录 - 即使它不是以以下开头
${
- 这意味着如果您的文件以[A-Z_]+}
(不太可能)开头 - 这些大写字母/下划线将“匹配”并被打印在输出的第一行
grep
+ 格式化
grep
也许更容易理解(感谢它的-o
/--only-matching
选项):
grep -o '${[A-Z_]\+}' FILE
- 但这不会格式化输出:通过管道
sed
可以做到这一点:例如。
grep -o '${[A-Z_]\+}' FILE | sed 's/${\(.*\)}/\1=/'
- 这不会删除重复项:通过管道输出
sort -u
来做到这一点,或者通过 awk 管道一次:
grep -o '${[A-Z_]\+}' FILE | awk -F '[{}]' '!a[$0]++{printf "%s=\n", $2}'
答案2
这就是我最终所做的:
cat file | grep -o '${\w*}' | sed -e 's|${||g' -e 's|}|=|g'
DB_HOST=
DB_PORT=
WEB_HOST=
WEB_PATH=
即使它不漂亮,但似乎工作得很好!
或者另一种方法(修改自https://unix.stackexchange.com/a/13467/229729):
cat file | sed -n -e 's/.*${\(\w\+\)}.*/\1=/p'