请帮忙。本地运行成功 在 awk 的帮助下实现了以下转换, 现在本地(带有 GNU Awk 4.0.2 版本的 Linux cent OS)运行完美,但问题出在远程版本上:
答案1
只要不是必须的sed
,您都可以使用 来完成此操作GNU awk
。然而,这会很长,因为sp.config.fal.proxyhost
可能需要在多个地方替换资源标识符,同时必须避免转换文件名,例如您的LiferayKeyStore.jks
.
因此,我提出一个awk
由两个规则组成的程序,一个用于必须转换 a 的行${ ... }
,一个用于仅需要转换开头的键名的情况(实际上,它是三个规则:第一个用于找到的情况${ ... }
,下一个用于仅key=value
找到语句的所有情况,一个用于“所有其他”情况,包括空行)。
假设您的输入文本位于名为 的文件中config.cfg
,它将如下所示:
awk '/\$\{[[:print:]]*\}/ {match($0,"([[:print:]]+)=\\${([[:print:]]+)}([[:print:]]*)",a); gsub("\\.","_",a[1]); gsub("\\.","_",a[2]); print toupper(a[1])": (("toupper(a[2])"))"a[3]; next}; /[[:print:]]+=[[:print:]]+/ {match($0,"([[:print:]]+)=([[:print:]]+)",a); gsub("\\.","_",a[1]); print toupper(a[1])": "a[2]; next}; {print}' config.cfg
这会执行以下操作
对于包含模式的所有行
${...}
,使用match()
来本地化模式“最多一个”的任意数量的可打印字符、带有封闭字符串的=
模式以及任何后续数量的可打印字符。${ ... }
所有用圆括号括起来的部分都被标记为“子表达式”,它们的实际的内容保存在数组中a
,作为a[1]
第一个子表达式等。然后我们使用gsub
ona[1]
部分key
,并用下划线替换所有句点。我们对${...}
第二个子表达式中包含的字符串执行相同的操作a[2]
。作为输出,我们打印a[1]
被替换的 a的大写转换版本,:
以及a[2]
( 但这次包含在(( ... ))
. 最后我们打印a[3]
未转换的版本,这只是“该行的其余部分” 。很重要:我们使用该next
指令跳过该行的进一步处理并重新开始下一行,否则该行可能会使用不同的转换进行两次处理(和输出)。如果我们没有偶然发现
${ ... }
,但是这条线做包含“key=value”语句(/[[:print:]]+=[[:print:]]+/
即任何非零数量的可打印字符,后跟=
,再后跟任何非零数量的可打印字符),然后仅对“key”部分应用替换和转换。再次,如果规则匹配,则跳过进一步处理。最后,如果上述规则都不符合,只需“按原样”打印该行即可。
编辑
如果存在空值的情况,即key=
,您还需要添加另一条规则来捕获该值:
awk '/\$\{[[:print:]]*\}/ {match($0,"([[:print:]]+)=\\${([[:print:]]+)}([[:print:]]*)",a); gsub("\\.","_",a[1]); gsub("\\.","_",a[2]); print toupper(a[1])": (("toupper(a[2])"))"a[3]; next}; /[[:print:]]+=[[:print:]]+/ {match($0,"([[:print:]]+)=([[:print:]]+)",a); gsub("\\.","_",a[1]); print toupper(a[1])": "a[2]; next}; /[[:print:]]+=[[:space:]]*/ {match($0,"([[:print:]]+)=([[:space:]]*)",a); gsub("\\.","_",a[1]); print toupper(a[1])":"; next}; {print}' config.cfg
不可能将第三条规则吸收到第二条规则中,因为由于 Base64 转换,您有key=value
一些对以 a 结尾。=