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

如何用AWK解析类YAML格式文件提取子键对应值?

实现基于类YAML结构的键值提取函数

问题背景

我有一个名为data.txt的文件,内容如下:

apple:
  weight: 15
  color: red
banana:
  weight: 30
  length: 12
grape:
  weight: 5
peach:
  weight: 25
  color: orange
  length: 4

需要用Bash和AWK编写一个get_value函数,实现根据父键和子键提取对应值的功能,要求满足以下测试场景:

function get_value(parent_key, child_key){ ... }

# Test 1
expected=15
actual=$(get_value apple weight) # 苹果有weight属性

# Test 2
expected=red
actual=$(get_value apple color)  # 苹果有color属性

# Test 3
expected=""
actual=$(get_value apple length)  # 苹果没有length属性

# Test 4
expected=""
actual=$(get_value banana color)  # 香蕉没有color属性

限制条件:不能使用Perl或Python,该文件并非标准YAML,仅包含两层键值结构,用冒号分隔。

我尝试过以下脚本,但无法处理子键不存在时返回空值的情况:

awk "/$key"'/ {found=1} found && /'"$child_key:"'/{print; found=0}' data.txt

解决方案:改进的AWK实现

以下是符合需求的get_value函数,通过精确匹配父键范围并处理未找到子键的场景:

get_value() {
    local parent_key="$1"
    local child_key="$2"
    
    awk -v parent="$parent_key" -v child="$child_key" '
        # 精确匹配目标父键行(避免部分匹配)
        $0 ~ "^" parent ":" {
            in_parent = 1
            next
        }
        # 遇到新的非缩进行(新父键),退出当前父键范围
        in_parent && !/^[[:space:]]/ {
            in_parent = 0
        }
        # 在父键范围内匹配目标子键
        in_parent && $0 ~ "^[[:space:]]+" child ":" {
            # 移除键名和冒号部分,提取值
            sub(/^[[:space:]]+[^:]+:[[:space:]]*/, "", $0)
            print $0
            in_parent = 0
        }
    ' data.txt
}

核心逻辑说明

  1. 精确父键匹配:使用^" parent ":"确保只匹配以目标父键开头且紧跟冒号的行,避免类似applepie:这类误匹配。
  2. 范围控制:通过in_parent变量标记是否处于目标父键的子项区域,当遇到新的非缩进行时,关闭标记,停止后续查找。
  3. 值提取与空值处理:匹配到子键后,用sub函数移除键名、冒号及前后空格,输出纯值;如果未找到子键,AWK不会输出任何内容,函数自然返回空字符串,符合测试要求。

测试验证

执行以下代码验证功能:

# Test 1
expected=15
actual=$(get_value apple weight)
echo "Test 1: expected=$expected, actual=$actual"

# Test 2
expected=red
actual=$(get_value apple color)
echo "Test 2: expected=$expected, actual=$actual"

# Test 3
expected=""
actual=$(get_value apple length)
echo "Test 3: expected='$expected', actual='$actual'"

# Test 4
expected=""
actual=$(get_value banana color)
echo "Test 4: expected='$expected', actual='$actual'"

输出结果:

Test 1: expected=15, actual=15
Test 2: expected=red, actual=red
Test 3: expected='', actual=''
Test 4: expected='', actual=''

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:52:51