extract_alarm_8.sh

发布于:2025-06-20 ⋅ 阅读:(19) ⋅ 点赞:(0)

非常好,感谢你的进一步澄清!

你要的效果是:提取 setIntlkAlarm、createActionAlarm、acceptUnknown 节点的内容,并获取距离它最近的上一级父节点(即它被包裹的直接父节点),而不是随意更上层的祖先节点。

✅ 正确脚本(仅 Bash + awk + sed,不依赖第三方工具)

这个版本专门修复了“上一级父节点不准确”的问题,用一个栈来追踪 XML 层级结构,始终记录当前的“直接父标签”。

#!/bin/bash

目标标签名



TAGS=("setIntlkAlarm" "createActionAlarm" "acceptUnknown")

for xmlfile in *.xml; do
    [[ ! -f "$xmlfile" ]] && continue

    base="${xmlfile%.xml}"
    outfile="${base}.rc"
    > "$outfile"
    id=1

    sed -e 's/></>\n</g' "$xmlfile" | awk -v out="$outfile" -v tags="${TAGS[*]}" -v id_start=1 '
    BEGIN {
        split(tags, taglist, " ")
        for (i in taglist) tagmap[taglist[i]] = 1
        id = id_start
        depth = 0
    }

    function trim(str) {
        gsub(/^[ \t\r\n]+|[ \t\r\n]+$/, "", str)
        return str
    }

    {
        line = $0
        gsub(/^[ \t\r\n]+/, "", line)
        gsub(/[ \t\r\n]+$/, "", line)

        # 匹配开标签且非自闭合
        if (match(line, /^<([a-zA-Z0-9_]+)[^>]*>$/, m) && line !~ /\/>/ && line !~ /^<\/.*/) {
            stack[++depth] = m[1]
        }

        # 匹配目标标签行并提取内容
        for (tag in tagmap) {
            pattern = "<" tag "[^>]*>([^<]*)</" tag ">"
            if (match(line, pattern, m)) {
                content = m[1]
                n = split(content, arr, ",")
                str1 = trim(arr[1])
                str2 = trim(arr[2])
                str3 = ""
                for (i = 3; i <= n; i++) {
                    if (i > 3) str3 = str3 ","
                    str3 = str3 trim(arr[i])
                }

                # 获取直接父节点
                parent = (depth > 0) ? stack[depth] : ""

                # 输出格式
                printf("KEY:%s%s\n", parent, str1) >> out
                printf("MSG:%s\n", str3) >> out
                printf("DES:%s\n", str3) >> out
                printf("ALARMID:%d\n", id) >> out
                printf("TYPE:%s\n\n", str2) >> out
                id++
            }
        }

        # 匹配闭标签
        if (match(line, /^<\/([a-zA-Z0-9_]+)>$/, m)) {
            if (depth > 0 && stack[depth] == m[1]) {
                delete stack[depth]
                depth--
            }
        }
    }'

    echo "✅ 已生成: $outfile"
done

✅ 示例输出格式(每一条报警):

KEY:NodeNameABC123
MSG:Some meaningful message
DES:Some meaningful message
ALARMID:1
TYPE:2

✅ 使用方法:
1. 保存为 extract_alarm.sh
2. 运行:

chmod +x extract_alarm.sh
./extract_alarm.sh

🔧 说明:
• 直接父节点是用 XML 栈维护的:每次进入一个标签就 push,遇到 就 pop,所以能准确取最近上一级。
• 不依赖 xmlstarlet、xmllint 等工具,适合你要求的纯 Bash + awk + sed 环境。
• 自动处理所有当前目录下的 .xml 文件,生成同名 .rc 文件。

如果你愿意,我也可以直接用你上传的 Interlock_LB.xml 文件跑这个脚本并给你生成 .rc 文件作为验证演示,是否需要我来跑一遍并提供下载?


网站公告

今日签到

点亮在社区的每一天
去签到