如何在Bash中根据YAML的billingcycle字段计算金额
问题描述
我有若干YAML文件,示例如下:
file1.yaml
- name: Saeed amount: '4500000.00' billingcycle: Annually - name: David amount: '9000000.00' billingcycle: Monthly -
file2.yaml
- name: Matthew amount: '8400000.00' billingcycle: Annually - name: Tom amount: '12000000.00' billingcycle: Quarterly - name: Sarah amount: '2400000.00' billingcycle: Semi-Annually -
需要处理所有.yaml文件,规则如下:
- 若
billingcycle为Quarterly,将amount值除以3; - 若为
Semi-Annually,除以6; - 若为
Annually,除以12; - 若为
Monthly,保留原amount值。
预期输出为对应TXT文件:
file1.txt
375000 9000000
file2.txt
700000 4000000 400000
之前写的两段代码都没得到预期结果:第一段输出格式不符合要求,第二段用case语句输出全是"nothing",求正确的Bash脚本实现需求。
解决方案
下面是能实现需求的Bash脚本,用awk处理YAML键值对,比纯Bash文本处理更可靠:
#!/bin/bash # 遍历当前目录下所有.yaml文件 for yaml_file in *.yaml; do # 生成对应的txt文件名(替换后缀) txt_file="${yaml_file%.yaml}.txt" # 清空目标文件,避免残留旧内容 > "$txt_file" # 用awk解析YAML并计算结果 awk ' # 跳过name行,无需处理 /^ name:/ { next } # 提取amount数值,去掉引号和末尾的.00 /^ amount:/ { amt = substr($2, 2, length($2)-2) gsub(/\.00$/, "", amt) } # 根据billingcycle计算结果并写入文件 /^ billingcycle:/ { cycle = $2 switch(cycle) { case "Annually": result = amt / 12 break case "Quarterly": result = amt / 3 break case "Semi-Annually": result = amt / 6 break case "Monthly": result = amt break } # 输出整数结果到目标txt文件 print int(result) > "'"$txt_file"'" } ' "$yaml_file" done
脚本说明
- 用
for循环遍历所有.yaml文件,自动生成对应的.txt输出文件; - awk部分专门适配YAML结构:
- 跳过不需要的
name行; - 提取
amount时,去掉前后引号和末尾的.00,转成纯整数; - 根据
billingcycle类型计算结果,最后输出整数到目标文件;
- 跳过不需要的
- 这种方式能准确对应每个条目,避免纯Bash处理文本时容易出现的格式匹配问题。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

