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

如何在Shell脚本中用数组复用逻辑处理YAML视图与表数据

问题描述

我写了一个Shell脚本用来读取YAML文件并做数据处理,YAML文件结构如下:

view:
    schema1.view1:/some-path/view1.sql
    schema2.view2:/some-path/view2.sql
tables:
    schema1.table1:/some-path/table1.sql
    schema2.table2:/some-path/table2.sql
end

期望输出格式为:

schema:schema1
object:view1
fileloc:/some-path/view1.sql

schema:schema2
object:view2
fileloc:/some-path/view2.sql

schema:schema1
object:table1
fileloc:/some-path/table1.sql

schema:schema2
object:table2
fileloc:/some-path/table2.sql

当前我用以下Shell代码读取YAML文件:

#!/bin/bash

input=./file.yaml

viewData=$(sed '/view/,/tables/!d;/tables/q' $input|sed '1d;$d')
tableData=$(sed '/tables/,/end/!d;/end/q' $input|sed '1d;$d')

其中viewData和tableData分别存储对应的数据。之后我用for循环处理table数据:

for line in $tableData; do
        field=`echo $line | cut -d: -f1`
        schema=`echo $field | cut -d. -f1`
        object=`echo $field | cut -d. -f2`
        fileLoc=`echo $line | cut -d: -f2`

        echo "schema=$schema"
        echo "object=$object"
        echo "fileloc=$fileLoc"
done

但处理view数据时需要重复写相同逻辑,请问如何在Shell脚本中用数组或其他方式复用该循环逻辑,同时处理视图与表数据?

解决方案

方法1:封装处理逻辑为函数

把重复的循环逻辑封装成Shell函数,只需编写一次处理代码,分别传入viewData和tableData即可完成两类数据的处理。

修改后的完整脚本:

#!/bin/bash

input=./file.yaml

# 封装通用处理逻辑为函数
process_data() {
    local data="$1"
    for line in $data; do
        field=$(echo "$line" | cut -d: -f1)
        schema=$(echo "$field" | cut -d. -f1)
        object=$(echo "$field" | cut -d. -f2)
        # 用-f2-替代-f2,避免路径含冒号时被截断
        fileLoc=$(echo "$line" | cut -d: -f2-)

        echo "schema:$schema"
        echo "object:$object"
        echo "fileloc:$fileLoc"
        echo  # 空行分隔每个对象
    done
}

# 提取视图和表的数据块
viewData=$(sed '/view/,/tables/!d;/tables/q' "$input" | sed '1d;$d')
tableData=$(sed '/tables/,/end/!d;/end/q' "$input" | sed '1d;$d')

# 调用函数处理两类数据
process_data "$viewData"
process_data "$tableData"

方法2:用数组批量管理数据块

如果后续可能新增更多类似数据块(比如functions:),可以用关联数组存储数据块的起始/结束标记,遍历数组统一处理,扩展性更强。

示例脚本:

#!/bin/bash

input=./file.yaml

# 封装单条数据的处理函数
process_line() {
    local line="$1"
    field=$(echo "$line" | cut -d: -f1)
    schema=$(echo "$field" | cut -d. -f1)
    object=$(echo "$field" | cut -d. -f2)
    fileLoc=$(echo "$line" | cut -d: -f2-)

    echo "schema:$schema"
    echo "object:$object"
    echo "fileloc:$fileLoc"
    echo
}

# 定义数据块的起始标记和对应的结束标记
declare -A data_blocks=(
    ["view"]="tables"
    ["tables"]="end"
)

# 遍历所有数据块处理
for block_start in "${!data_blocks[@]}"; do
    block_end=${data_blocks[$block_start]}
    # 提取当前数据块的内容
    block_data=$(sed "/$block_start/,/$block_end/!d;/$block_end/q" "$input" | sed '1d;$d')
    # 处理数据块内的每一行
    for line in $block_data; do
        process_line "$line"
    done
done

新增数据块时,仅需在data_blocks数组中添加新的起始/结束标记对,无需修改处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:50:37