You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

awk提取键值对生成Shell脚本遇语法错误,求排查与解决方案

问题描述

现有文件中的一行内容如下:

show = "holder";  // [holder: Dispensor,dryer: Hair Dryer,bidet: Bedit,cover: Cover,wall mount: Wall Mount,screwdriver cutout: Screwdriver Cutout, assembly: Assembly,exploded: Exploded,vitamin: Vitamin]

需要生成Shell脚本,针对方括号内的每一组xxx:yyy键值对,输出如下格式的命令行:

openscad --quiet --export-format binstl -D 'show=xxx' -o xxx.stl $1

注:原需求示例中的--quite是拼写错误,应为--quiet,且--export-format后缺少格式参数binstl,已做修正。

尝试了三段awk代码均触发语法错误,详情如下:

第一段代码

match($0, /\[[^\n\]]*\]$/) {                # 提取[xx:yy, aa:bb]部分
    s = substr($0, RSTART+1, RLENGTH-2);    # 去掉首尾的[]
    n = split(s, arr,";");                  # 拆分键值对
    for(x in arr) {                         # 遍历每个键值对
        match(arr[x], /([^\n:]+)/, b) {     # 提取键值对的第一个字段
            print subsgtr(b[1], RSTART, RLENGTH)
        }
    }
}

报错信息:

gawk: prog:5:       match(arr[x], /([^\n:]+)/, b) {     # get the first field of the pair
gawk: prog:5:                                     ^ syntax error

第二段代码

match($0, /\[[^\n\]]*\]$/) {                # 提取[xx:yy, aa:bb]部分
    s = substr($0, RSTART+1, RLENGTH-2);    # 去掉首尾的[]
    n = split(s, arr,";");                  # 拆分键值对
    for(x in arr) {                         # 遍历每个键值对
        arr[x] ~ /([^\n:]+)/ print 
    }
}

报错信息:

gawk: prog:5:       arr[x] ~ /([^\n:]+)/ print 
gawk: prog:5:                            ^ syntax error

第三段代码

match($0, /\[[^\n\]]*\]$/) {                # 提取[xx:yy, aa:bb]部分
    s = substr($0, RSTART+1, RLENGTH-2);    # 去掉首尾的[]
    n = split(s, arr,";");                  # 拆分键值对
    for(x in arr) {                         # 遍历每个键值对
        arr[x] ~ /([^\n:]+)/ { print }
    }
}

报错信息:

gawk: prog:5:       arr[x] ~ /([^\n:]+)/ { print }
gawk: prog:5:                            ^ syntax error

需要解释上述错误原因,并给出能实现需求的正确方案。


错误原因解析

第一段代码错误

  1. match函数语法违规:awk中match()是函数调用,不能直接后跟代码块{},需先执行匹配,再通过if判断结果或直接使用匹配后的内置变量。
  2. 拼写错误:subsgtr是substr的笔误。
  3. 分隔符错误:拆分键值对应该用逗号,,而非分号;。

第二段代码错误

awk的条件判断后必须用{}包裹执行语句,或显式添加if关键字,直接写条件 print不符合语法规范。

第三段代码错误

用~做正则匹配时,不能直接将条件与代码块连写,必须加上if关键字,正确写法应为if (arr[x] ~ /([^\n:]+)/) { print }。


正确实现方案

以下awk脚本可完成需求,同时修正了原openscad命令的参数顺序错误:

# 匹配行尾方括号内的内容,捕获到m[1]中
match($0, /\[([^\]]+)\]$/, m) {
    # 拆分键值对,自动处理逗号前后的空格
    n = split(m[1], pairs, /,\s*/)
    # 遍历所有键值对(用索引遍历保证顺序)
    for (i=1; i<=n; i++) {
        # 拆分键和值
        split(pairs[i], kv, /:/)
        # 去除键名前后的空格(适配带空格的键名如wall mount)
        gsub(/^\s+|\s+$/, "", kv[1])
        # 生成目标命令行
        printf "openscad --quiet --export-format binstl -D 'show=%s' -o %s.stl \$1\n", kv[1], kv[1]
    }
}

使用步骤

  1. 将上述代码保存为gen_scad_cmds.awk
  2. 执行命令生成Shell脚本:
awk -f gen_scad_cmds.awk 你的输入文件名 > generate_stl.sh
chmod +x generate_stl.sh
  1. 运行生成的脚本:
./generate_stl.sh 你的openscad源文件.scad

关键说明

  • 用match()的第三个参数直接捕获方括号内的内容,避免手动截取字符串的繁琐操作
  • 拆分键值对时使用/,\s*/正则,自动处理逗号后的空格
  • 用gsub()清理键名前后的空格,适配带空格的键名
  • 修正了原openscad命令的参数顺序:--export-format后必须跟格式参数binstl,调整-D参数到正确位置,同时修正了--quite的拼写错误

内容的提问来源于stack exchange,提问作者MyTallest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:57:50