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

如何用sed/grep/awk从XML提取IP、协议、端口生成带列名的CSV?

嘿,这个问题我太有发言权了!用grep/sed单独提取字段不难,但要规整成CSV列确实有点麻烦——而且更重要的是,用正则硬怼XML很容易踩坑(比如标签换行、属性顺序变化、嵌套结构),所以优先推荐结构化的XML解析工具,当然如果你的XML格式特别规整,用awk组合也能快速搞定。下面给你几个实用方案:

方案1:用xmllint + awk(推荐,结构化解析更可靠)

xmllint是专门处理XML的工具,支持XPath查询,能精准定位你要的字段,完全不用担心正则匹配的各种意外。

假设你的XML结构是类似这样的(属性形式):

<services>
  <endpoint ip="192.168.1.1" protocol="TCP" port="80"/>
  <endpoint ip="10.0.0.5" protocol="UDP" port="53"/>
</services>

你可以先用xmllint提取所有目标属性,再用awk把每3个属性组拼成一行CSV:

# 先提取所有IP、协议、端口属性,再整理成CSV
xmllint --xpath '//endpoint/@ip | //endpoint/@protocol | //endpoint/@port' your_file.xml | \
awk -F'"' 'BEGIN{print "IPAddress,Protocol,Port"} {i++} i%3==1{ip=$2} i%3==2{proto=$2} i%3==0{print ip","proto","$2}' > output.csv

如果你的XML是子元素形式(比如<ip>192.168.1.1</ip>),只需要把XPath改成提取文本内容:

xmllint --xpath '//endpoint/ip/text() | //endpoint/protocol/text() | //endpoint/port/text()' your_file.xml | \
awk 'BEGIN{print "IPAddress,Protocol,Port"} {i++} i%3==1{ip=$0} i%3==2{proto=$0} i%3==0{print ip","proto","$0}' > output.csv

方案2:用awk单独处理(适合XML格式极规整的场景)

如果你的XML每行就是一个包含三个目标字段的节点(比如每行都是<item ip="x" protocol="y" port="z"/>),那用awk一次性提取也很高效:

awk '
BEGIN{print "IPAddress,Protocol,Port"} 
match($0, /ip="([0-9.]+)"/, ip) && 
match($0, /protocol="([A-Za-z]+)"/, proto) && 
match($0, /port="([0-9]+)"/, port) {
    print ip[1]","proto[1]","port[1]
}
' your_file.xml > output.csv

这个命令会先打印CSV表头,然后每行匹配三个字段,只要三个字段都存在就输出一行。

方案3:用Python脚本(灵活,适合复杂XML结构)

如果你的XML嵌套复杂,或者需要后续扩展逻辑(比如过滤无效IP、补全缺省值),用Python的标准库处理会更稳妥:

import xml.etree.ElementTree as ET
import csv

# 解析XML文件
tree = ET.parse('your_file.xml')
root = tree.getroot()

# 写入CSV
with open('output.csv', 'w', newline='', encoding='utf-8') as csvfile:
    fieldnames = ['IPAddress', 'Protocol', 'Port']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    
    # 遍历所有目标节点(根据你的XML结构修改路径,比如.//endpoint)
    for node in root.findall('.//endpoint'):
        # 提取字段:如果是属性用get(),子元素用find('ip').text
        ip = node.get('ip')
        protocol = node.get('protocol')
        port = node.get('port')
        
        # 跳过缺失字段的节点
        if ip and protocol and port:
            writer.writerow({
                'IPAddress': ip,
                'Protocol': protocol,
                'Port': port
            })

重要提醒

尽量别用纯grep/sed组合处理XML!XML的格式灵活性很高(比如属性换行、标签嵌套),正则很容易漏匹配或者误匹配,结构化工具才是更靠谱的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:05:11