如何用awk处理白名单文件的解析与格式转换?
AWK解决方案:白名单文件格式转换
以下是实现需求的AWK脚本,能够处理带方括号多函数、带引号参数的白名单格式,并将其展开为指定的输出结构:
#!/usr/bin/awk -f BEGIN { FS = " " } { # 提取行尾的标记部分(比如offline_install=true) tags = "" for (i=2; i<=NF; i++) { tags = tags (tags ? " " : "") $i } # 拆分模块名和函数部分 split($1, mod_func, ":") module = mod_func[1] func_block = mod_func[2] # 移除函数块的方括号包裹 gsub(/^\[|\]$/, "", func_block) # 拆分多个函数(忽略引号/括号内的逗号) func_count = split_funcs(func_block, funcs) for (idx=1; idx<=func_count; idx++) { process_func(module, funcs[idx], tags) } } # 处理单个函数:输出函数行+参数行 function process_func(module, func_str, tags, parts, func_name, args_str, arg_count, args) { if (match(func_str, /^([^()]+)\((.*)\)$/, parts)) { func_name = parts[1] args_str = parts[2] # 输出函数本身的行 printf "%s:%s %s\n", module, func_name, tags # 拆分参数(处理带引号的参数) if (args_str != "") { arg_count = split_args(args_str, args) for (arg_idx=1; arg_idx<=arg_count; arg_idx++) { printf "%s:%s:%s %s\n", module, func_name, args[arg_idx], tags } } } else { # 兼容无括号的函数格式(如果存在) printf "%s:%s %s\n", module, func_str, tags } } # 拆分多个函数:仅在括号外、引号外的逗号处分割 function split_funcs(str, arr, i, len, char, in_quote, in_paren, start, cnt) { len = length(str) in_quote = 0 in_paren = 0 start = 1 cnt = 0 for (i=1; i<=len; i++) { char = substr(str, i, 1) if (char == "\"") { in_quote = !in_quote } else if (char == "(" && !in_quote) { in_paren++ } else if (char == ")" && !in_quote) { in_paren-- } else if (char == "," && !in_quote && in_paren == 0) { cnt++ arr[cnt] = substr(str, start, i - start) start = i + 1 } } if (start <= len) { cnt++ arr[cnt] = substr(str, start) } return cnt } # 拆分参数:仅在引号外的逗号处分割,同时去除参数前后空格 function split_args(str, arr, i, len, char, in_quote, start, cnt) { len = length(str) in_quote = 0 start = 1 cnt = 0 for (i=1; i<=len; i++) { char = substr(str, i, 1) if (char == "\"") { in_quote = !in_quote } else if (char == "," && !in_quote) { cnt++ arr[cnt] = substr(str, start, i - start) start = i + 1 } } if (start <= len) { cnt++ arr[cnt] = substr(str, start) } # 清理参数前后的空白字符 for (i=1; i<=cnt; i++) { gsub(/^[[:space:]]+|[[:space:]]+$/, "", arr[i]) } return cnt }
用法说明
- 将脚本保存为
whitelist_convert.awk - 赋予执行权限:
chmod +x whitelist_convert.awk - 运行脚本处理文件:
./whitelist_convert.awk whitelist.txt
示例验证
输入(whitelist.txt)
network:[connect("192.168.1.1", "admin password"),disconnect()] offline_install=true storage:list("/mnt/shared folder") utils:cleanup() offline_install=false
输出
network:connect offline_install=true network:connect:"192.168.1.1" offline_install=true network:connect:"admin password" offline_install=true network:disconnect offline_install=true storage:list storage:list:"/mnt/shared folder" utils:cleanup offline_install=false
关键逻辑说明
- 标记提取:把行内第一个字段以外的所有内容作为标记,完整保留原始格式
- 函数拆分:通过状态机识别引号和括号的嵌套,确保仅拆分独立的函数项
- 参数处理:同样使用状态机避免拆分引号内的逗号,保留带空格的完整参数
- 格式输出:严格按照要求展开函数和参数,每行对应一个条目并携带标记
内容的提问来源于stack exchange,提问作者Andrei Caba
相关产品推荐
相关产品推荐

