使用 AWK 转换不同类型的字符串
Convert different type Of strings with AWK
我的配置文件中有以下变量:
tags = {
environment = "development",
provider = "ServiceOne",
ansible_role = "nfs-role",
comment = "mysql"
}
line = "b01"
my_lb_ports = "[53, 80, 443, 389, 636, 3268, 3269, 6443]"
dns_servers = "[\"8.8.8.8\", \"9.9.9.9\"]"
对于我的管道,我需要将其转换为以下内容:
tfh pushvars -overwrite-all -dry-run false -hcl-var "tags={environment=\"development\", provider=\"ServiceOne\", ansible_role=\"nfs-rolep\",comment= \"mysql\"}"
tfh pushvars -overwrite-all -dry-run false -hcl-var "line=\"b01\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "my_lb_ports=[\"53\", \"80\", \"443\", \"389\", \"636\", \"3268\", \"3269\", \"6443\"]"
tfh pushvars -overwrite-all -dry-run false -hcl-var "dns_servers=[\"8.8.8.8\", \"9.9.9.9\"]"
以下脚本是在@Ed Morton 的支持下创建的,但它仍然无法识别所有模式:
#!/usr/bin/env bash
(( $# == 2 )) || { echo "==> Usage: ./${0##*/} <<INPUT_FILE>> <<OUTPUT_FILE>>"; exit 1; }
vars_file=""
output_file=""
awk '
BEGIN {
ORS = ""
print "tfh pushvars -overwrite-all -dry-run false -hcl-var \""
}
NF && !/^#/ {
gsub(/[[:space:]]/,"")
gsub(/"/,"\\&")
print
}
END {
print "\"\n"
}
' "$vars_file" > "$output_file"
awk -F'=' '{ gsub( /\x22/ ,"\x5c\&", ); gsub( / / ,"", ); gsub( / / ,"", ); print "tfh pushvars -overwrite-all -dry-run false -hcl-var \x22" "=" "\x22"}' "$vars_file" >> "$output_file"
这是一个好的开始,您需要了解如何调整输出行中的 "
s:
$ cat tst.sh
#!/usr/bin/env bash
(( $# == 2 )) || { echo "==> Usage: ./${0##*/} <<INPUT_FILE>> <<OUTPUT_FILE>>"; exit 1; }
vars_file=""
output_file=""
awk '
BEGIN {
ORS = ""
beg = "tfh pushvars -overwrite-all -dry-run false -hcl-var \""
end = "\"\n"
}
/^[[:alnum:]_]+[[:space:]]*=/ {
gotBlockBeg = 1
gotBlockEnd = ( $NF == "{" ? 0 : 1 )
}
gotBlockBeg {
block = block [=10=]
if ( $NF == "}" ) {
gotBlockEnd = 1
}
}
gotBlockEnd {
gsub(/[[:space:]]/,"",block)
gsub(/"/,"\\&",block)
print beg block end
gotBlockBeg = gotBlockEnd = 0
block = ""
}
' "$vars_file" > "$output_file"
$ ./tst.sh file foo
$ cat foo
tfh pushvars -overwrite-all -dry-run false -hcl-var "tags={environment=\"development\",provider=\"ServiceOne\",ansible_role=\"nfs-role\",comment=\"mysql\"}"
tfh pushvars -overwrite-all -dry-run false -hcl-var "line=\"b01\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "my_lb_ports=\"[53,80,443,389,636,3268,3269,6443]\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "dns_servers=\"[\"8.8.8.8\",\"9.9.9.9\"]\""
在任何您不了解 awk 脚本或 运行 使用 gawk 调试器 (gawk -D ...
) 的地方添加调试 print
语句。
我的配置文件中有以下变量:
tags = {
environment = "development",
provider = "ServiceOne",
ansible_role = "nfs-role",
comment = "mysql"
}
line = "b01"
my_lb_ports = "[53, 80, 443, 389, 636, 3268, 3269, 6443]"
dns_servers = "[\"8.8.8.8\", \"9.9.9.9\"]"
对于我的管道,我需要将其转换为以下内容:
tfh pushvars -overwrite-all -dry-run false -hcl-var "tags={environment=\"development\", provider=\"ServiceOne\", ansible_role=\"nfs-rolep\",comment= \"mysql\"}"
tfh pushvars -overwrite-all -dry-run false -hcl-var "line=\"b01\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "my_lb_ports=[\"53\", \"80\", \"443\", \"389\", \"636\", \"3268\", \"3269\", \"6443\"]"
tfh pushvars -overwrite-all -dry-run false -hcl-var "dns_servers=[\"8.8.8.8\", \"9.9.9.9\"]"
以下脚本是在@Ed Morton 的支持下创建的,但它仍然无法识别所有模式:
#!/usr/bin/env bash
(( $# == 2 )) || { echo "==> Usage: ./${0##*/} <<INPUT_FILE>> <<OUTPUT_FILE>>"; exit 1; }
vars_file=""
output_file=""
awk '
BEGIN {
ORS = ""
print "tfh pushvars -overwrite-all -dry-run false -hcl-var \""
}
NF && !/^#/ {
gsub(/[[:space:]]/,"")
gsub(/"/,"\\&")
print
}
END {
print "\"\n"
}
' "$vars_file" > "$output_file"
awk -F'=' '{ gsub( /\x22/ ,"\x5c\&", ); gsub( / / ,"", ); gsub( / / ,"", ); print "tfh pushvars -overwrite-all -dry-run false -hcl-var \x22" "=" "\x22"}' "$vars_file" >> "$output_file"
这是一个好的开始,您需要了解如何调整输出行中的 "
s:
$ cat tst.sh
#!/usr/bin/env bash
(( $# == 2 )) || { echo "==> Usage: ./${0##*/} <<INPUT_FILE>> <<OUTPUT_FILE>>"; exit 1; }
vars_file=""
output_file=""
awk '
BEGIN {
ORS = ""
beg = "tfh pushvars -overwrite-all -dry-run false -hcl-var \""
end = "\"\n"
}
/^[[:alnum:]_]+[[:space:]]*=/ {
gotBlockBeg = 1
gotBlockEnd = ( $NF == "{" ? 0 : 1 )
}
gotBlockBeg {
block = block [=10=]
if ( $NF == "}" ) {
gotBlockEnd = 1
}
}
gotBlockEnd {
gsub(/[[:space:]]/,"",block)
gsub(/"/,"\\&",block)
print beg block end
gotBlockBeg = gotBlockEnd = 0
block = ""
}
' "$vars_file" > "$output_file"
$ ./tst.sh file foo
$ cat foo
tfh pushvars -overwrite-all -dry-run false -hcl-var "tags={environment=\"development\",provider=\"ServiceOne\",ansible_role=\"nfs-role\",comment=\"mysql\"}"
tfh pushvars -overwrite-all -dry-run false -hcl-var "line=\"b01\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "my_lb_ports=\"[53,80,443,389,636,3268,3269,6443]\""
tfh pushvars -overwrite-all -dry-run false -hcl-var "dns_servers=\"[\"8.8.8.8\",\"9.9.9.9\"]\""
在任何您不了解 awk 脚本或 运行 使用 gawk 调试器 (gawk -D ...
) 的地方添加调试 print
语句。