Last active
November 18, 2021 21:03
-
-
Save StudioEtrange/152e7bd0ac278b175663d11ab5db5d81 to your computer and use it in GitHub Desktop.
Awk function that can in any text or configuration file substitute a key with its own value, if its value is assigned earlier in the file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# In any text or configuration file substitute a key with its own value, if its value is assigned earlier in the file and the key is referenced with {{key}} | |
# This could be used on any text file, i.e an .ini file or a docker-compose env file | |
# The mechanism works like in shell script variable syntax in some ways : assignation, declaration, resolution order and comment symbol (#) | |
# Usage : substitute_key_in_file "<file_path>" | |
# Input file content: | |
# N=10 | |
# The number is {{N}} | |
# # FOO={{N}} | |
# A=1 | |
# B={{A}} | |
# C={{B}} | |
# X={{Y}} | |
# Y=4 | |
# X={{Y}} | |
# Result file content: | |
# N=10 | |
# # The number is 10 | |
# # FOO=10 | |
# A=1 | |
# B=1 | |
# C=1 | |
# X={{Y}} | |
# Y=4 | |
# X=4 | |
substitute_key_in_file() { | |
local _file="$1" | |
local _temp=$(mktmp) | |
awk -F= ' | |
function parsekey(str) { | |
# if there is a value assignation to a key into this string | |
# update val array | |
if (match(str,/^([^=#]*)=(.*)/,tmp)) { | |
val[tmp[1]]=tmp[2]; | |
} | |
} | |
# fill the key array which contains all existing key | |
/^[^=#]*=/ { | |
# FNR=NR only when reading first file | |
if (FNR==NR) { | |
key[$1]=1; | |
next; | |
} | |
} | |
/.*/ { | |
# FNR=NR only when reading first file | |
if (FNR==NR) { | |
next; | |
} | |
} | |
# this block is triggered at each line only if not bypassed by next | |
# so this block is really triggered only when reading second file | |
{ | |
for (k in key) { | |
# transform any reference to the keyy in current line into its value, if it has a known value | |
# key[] list all existing keys in file | |
# val[] list only key which have a known value | |
if (k in val) { | |
# we replace any reference to the key with its value with gsub in current line | |
gsub("{{"k"}}", val[k]); | |
} | |
} | |
# re-parse the current line to find any value assignation to a key | |
parsekey($0); | |
print $0; | |
} | |
' "${_file}" "${_file}" > "${_temp}" | |
cat "${_temp}" > "${_file}" | |
rm -f "${_temp}" | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment