如果 shell 环境中存在键,如何替换键值文件中的值?

How to substitute values in a key-value file if keys exists in shell environment?

我有一个如下所示的文件,键值对由 = 分隔。我已经将一些变量导出到我的 shell。现在我想要一个 shell 脚本,如果这些键已经存在于环境变量中或导出到 shell,它可以用相应键的值替换这些键。

我可以使用 envsubst,但我不想在美元符号前加上这些默认值。如果有任何其他工具(如 envsubst)可以帮助我替换字符串值,请同时参考。

foo.yaml

PROJECT_NAME=test
DOMAIN_NAME=test.localhost
NETWORK_NAME=traefik-network    
ENVIRONMENT=dev
DRUPAL_VERSION=8
MYSQL_HOSTNAME=test.mariadb
MYSQL_DATABASE=drupal
MYSQL_USER=test
MYSQL_PASSWORD=pass
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=pass

我想,您正在寻找如下内容。

> cat foo.yaml
PROJECT_NAME=test
DOMAIN_NAME=test.localhost
NETWORK_NAME=traefik-network
ENVIRONMENT=dev
DRUPAL_VERSION=8
MYSQL_HOSTNAME=test.mariadb
MYSQL_DATABASE=drupal
MYSQL_USER=test
MYSQL_PASSWORD=pass
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=pass
>
> export ENVIRONMENT=sit
> export DRUPAL_VERSION=10
> export MYSQL_PASSWORD="*****"
>
> perl -lpe ' s/(.*)=(.*)/sprintf("%s=%s","",$ENV{}? $ENV{}:)/ge ' foo.yaml
PROJECT_NAME=test
DOMAIN_NAME=test.localhost
NETWORK_NAME=traefik-network
ENVIRONMENT=sit
DRUPAL_VERSION=10
MYSQL_HOSTNAME=test.mariadb
MYSQL_DATABASE=drupal
MYSQL_USER=test
MYSQL_PASSWORD=*****
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=pass
>

这有帮助吗?

请注意,如果您有写入权限,可以在 Perl 中使用 -i 开关覆盖文件

> perl -i -lpe ' s/(.*)=(.*)/sprintf("%s=%s","",$ENV{}? $ENV{}:)/ge ' foo.yaml
> cat foo.yaml
PROJECT_NAME=test
DOMAIN_NAME=test.localhost
NETWORK_NAME=traefik-network
ENVIRONMENT=sit
DRUPAL_VERSION=10
MYSQL_HOSTNAME=test.mariadb
MYSQL_DATABASE=drupal
MYSQL_USER=test
MYSQL_PASSWORD=*****
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=pass
>

AWK 解决方案。

> awk -F"=" ' { =ENVIRON[]?ENVIRON[]:; printf("%s=%s\n",,) } ' foo.yaml

可以进一步缩短为

> awk -F"=" ' { printf("%s=%s\n",,ENVIRON[]?ENVIRON[]:) } ' foo.yaml

处理空行

> awk -F"=" ' { if (!/^\s*$/) [=14=]=sprintf("%s=%s",,ENVIRON[]?ENVIRON[]:) }1 ' foo.yaml