如何提取XML/SVG分段并以段内id为文件名生成独立文件?
提取SVG片段并按ID保存为独立文件
没问题,我来帮你搞定这个需求!你要从一个包含多个SVG片段的文件里,把每个以<?xml开头、</svg>结尾的段提取出来,还得用每个段里的id属性值作为文件名对吧?不用纠结sed的组合正则,我给你几个实用的方案,保证能解决问题:
方案1:用sed+循环(适合熟悉sed的场景)
这个方法分两步:先提取所有的id值,再逐个匹配对应的SVG块并保存。执行下面的命令就行:
sed -n 's/.*id="\([^"]*\)".*/\1/p' Original.svg | while read id; do sed -n "/<?xml.*id=\"$id\"/,/<\/svg>/p" Original.svg > "$id.svg" done
简单解释:
- 第一行的
sed命令专门提取所有SVG块里的id值,输出每个id的内容 - 然后通过
while read循环遍历每个id,用sed的地址范围匹配(从包含该id的<?xml行开始,到</svg>行结束),把这段内容输出到以id.svg命名的文件里
方案2:用awk(更高效,只读取一次文件)
如果你的原文件很大,awk方案会更高效,因为它只需要读取一次原文件就能完成所有提取:
awk ' /<?xml/ { # 遇到新的SVG块开头,先把之前缓存的内容写入文件(如果有的话) if (buffer != "") { print buffer > filename close(filename) buffer = "" } } { # 把当前行加入缓存(加空格是为了处理原文件一行到底的情况) buffer = buffer $0 " " # 提取当前块的id作为文件名 if (/id="[^"]*"/) { match($0, /id="([^"]*)"/, arr) filename = arr[1] ".svg" } } /<\/svg>/ { # 遇到SVG块结尾,把缓存内容写入文件并清空 print buffer > filename close(filename) buffer = "" } ' Original.svg
简单解释:
- 脚本会逐行扫描原文件,遇到
<?xml就初始化缓存,遇到id属性就记录文件名,遇到</svg>就把缓存的整个SVG块写入对应的文件 - 加
close(filename)是为了避免打开过多文件句柄,防止报错
注意事项
- 确保原文件里每个SVG块的
id都是唯一的,不然后面的块会覆盖前面同名的文件 - 不管原文件里的SVG块是一行到底还是换行排版,这两个方案都能正常处理
- 如果
id里包含特殊字符(比如空格、斜杠),需要调整正则表达式做转义,但一般SVG的id都是符合XML规范的标识符,不会有这种问题
内容的提问来源于stack exchange,提问作者octosquidopus
相关产品推荐
相关产品推荐

