如何用awk将.deb包依赖转换为Graphviz .dot格式依赖图?
编写convert.awk生成Graphviz .dot文件的完整方案
我来帮你搞定这个convert.awk脚本,专门用来把deb包的依赖关系转换成Graphviz能识别的.dot文件。下面是一步步的实现方案:
核心思路
我们要做的就是从deb包的控制信息里提取两个关键字段:
Package:当前包的名称,作为Graphviz的节点Depends:当前包依赖的其他包,我们要把每个依赖包名提取出来,生成当前包到依赖包的有向边
另外要注意deb文件的格式细节:每个包的信息块用空行分隔,长字段(比如Depends)可能会折行,后续行以空格开头。
完整的convert.awk代码
#!/usr/bin/awk -f # 初始化:输出Graphviz的有向图头部,顺便设置点和边的样式 BEGIN { print "digraph package_dependencies {" print " node [shape=box, style=filled, fillcolor=lightblue];" print " edge [color=gray];" FS = ": " # 把字段分隔符设为": ",方便直接提取键值对 } # 处理空行:一个包的信息块结束,开始处理依赖关系 /^$/ { process_dependencies() reset_vars() next } # 提取当前包的名称 /^Package:/ { pkg_name = $2 } # 提取依赖列表,处理可能的折行 /^Depends:/ { dep_string = $2 # 检查是否有折行的依赖内容 while (getline next_line > 0) { if (next_line ~ /^ /) { # 折行的内容开头是空格,去掉空格后拼接到依赖字符串 dep_string = dep_string ", " substr(next_line, 2) } else { # 把非折行的行放回缓冲区,让awk继续处理 ungetline break } } } # 处理最后一个包(因为最后一个包后面可能没有空行) END { process_dependencies() print "}" } # 自定义函数:处理依赖关系并输出Graphviz边 function process_dependencies() { if (pkg_name != "" && dep_string != "") { # 把依赖字符串按逗号分割成数组 split(dep_string, dep_array, /, /) for (i in dep_array) { # 提取纯包名:去掉版本号部分(从第一个"-数字"截断) split(dep_array[i], dep_parts, /-[0-9]/) clean_dep = dep_parts[1] # 输出边 printf " \"%s\" -> \"%s\";\n", pkg_name, clean_dep } } } # 自定义函数:重置变量,准备处理下一个包 function reset_vars() { pkg_name = "" dep_string = "" }
使用步骤
- 给脚本加上执行权限(可选,也可以直接用awk调用):
chmod +x convert.awk - 执行脚本生成.dot文件:
awk -f convert.awk deb-9-packages.deb > output.dot # 或者用执行权限的方式:./convert.awk deb-9-packages.deb > output.dot - 用Graphviz生成可视化图形(比如PNG格式):
dot -Tpng output.dot -o package_deps.png
关键细节说明
- 处理折行依赖:有些deb包的Depends字段太长会自动折行,后续行以空格开头,脚本里用
getline读取这些行并拼接成完整的依赖字符串 - 提取纯包名:依赖项的格式是
libghc-base-dev-4.9.0.0-1bac3,我们用/-[0-9]/作为分隔符,取第一部分就得到不带版本号的纯包名 - Graphviz样式优化:设置节点为浅蓝色填充的方框,边为灰色,让生成的图形更清晰易读
内容的提问来源于stack exchange,提问作者Bergelius
相关产品推荐
相关产品推荐

