#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: preserve-env-values.sh [KEY...] For each KEY, copy the value from into only when the target value is missing or still looks like a placeholder. EOF } if [[ $# -lt 3 ]]; then usage >&2 exit 1 fi source_env_file="$1" target_env_file="$2" shift 2 for env_file in "${source_env_file}" "${target_env_file}"; do if [[ ! -f "${env_file}" ]]; then echo "Missing env file: ${env_file}" >&2 exit 1 fi done read_env_value() { local env_file="$1" local key="$2" local value value="$( awk -F= -v key="${key}" ' /^[[:space:]]*#/ || index($0, "=") == 0 { next } { name = $1 sub(/^[[:space:]]*export[[:space:]]+/, "", name) gsub(/^[[:space:]]+|[[:space:]]+$/, "", name) if (name == key) { value = substr($0, index($0, "=") + 1) } } END { print value } ' "${env_file}" )" value="${value%$'\r'}" value="${value#"${value%%[![:space:]]*}"}" value="${value%"${value##*[![:space:]]}"}" if [[ "${value}" == \"*\" && "${value}" == *\" ]]; then value="${value#\"}" value="${value%\"}" elif [[ "${value}" == \'*\' && "${value}" == *\' ]]; then value="${value#\'}" value="${value%\'}" fi printf '%s' "${value}" } should_preserve_value() { local value="$1" [[ -z "${value}" || "${value}" == placeholder || "${value}" == replace-with-* || "${value}" == *changeme* || "${value}" == *change-me* ]] } upsert_env_value() { local key="$1" local value="$2" local tmp_file tmp_file="$(mktemp "${target_env_file}.tmp.XXXXXX")" awk -v key="${key}" -v value="${value}" ' BEGIN { updated = 0 } /^[[:space:]]*#/ || index($0, "=") == 0 { print next } { name = $1 sub(/=.*/, "", name) sub(/^[[:space:]]*export[[:space:]]+/, "", name) gsub(/^[[:space:]]+|[[:space:]]+$/, "", name) if (name == key) { print key "=" value updated = 1 next } print } END { if (!updated) { print key "=" value } } ' "${target_env_file}" > "${tmp_file}" mv "${tmp_file}" "${target_env_file}" } for key in "$@"; do source_value="$(read_env_value "${source_env_file}" "${key}")" target_value="$(read_env_value "${target_env_file}" "${key}")" if [[ -n "${source_value}" ]] && should_preserve_value "${target_value}"; then upsert_env_value "${key}" "${source_value}" fi done