使用Bash创建含无序分散数据的表格的技术求助
嘿,我懂你现在的困扰——把分散在不同文件里的无序键值对整理成美观的表格确实有点棘手,不过awk绝对是干这个的绝佳工具!我来一步步给你拆解怎么实现,保证清晰好用。
核心思路
你的每个文件都是键 值 键 值...的无序结构,我们要做的就是:
- 先把所有文件里的键收集起来,作为表格的表头
- 遍历每个文件,把键值对存成关联数组
- 按表头顺序输出每个文件对应的值,缺失的键用
NA填充,同时保证列对齐
完整实现步骤
1. 提取所有唯一键(生成表头)
首先我们需要把所有文件里的键都捞出来,去重并排序,这样表头就统一了:
# 收集所有文件的键,去重后排序存为变量 headers=$(awk '{for(i=1;i<=NF;i+=2) keys[$i]} END{for(k in keys) print k}' file1 file2 | sort)
2. 用awk生成对齐的表格
接下来写一个awk脚本,读取所有文件,按表头格式输出数据,还可以加上文件名列方便区分:
awk -v headers="$headers" ' BEGIN { # 把表头字符串拆分成数组 n = split(headers, header_arr) # 打印表头(先加文件名列) printf "%-15s", "Filename" for(i=1;i<=n;i++) { printf "%-15s", header_arr[i] # %-15s表示左对齐,宽度15,可按需调整 } print "" # 打印分隔线,让表格更清晰 print "---------------------------------------------------------------------------" } # 处理每个文件的内容 { # 清空当前文件的临时数据数组 delete data # 遍历当前行的键值对,存入数组 for(i=1;i<=NF;i+=2) { data[$i] = $(i+1) } # 先打印当前文件名 printf "%-15s", FILENAME # 按表头顺序输出对应的值,缺失的键填NA for(i=1;i<=n;i++) { key = header_arr[i] printf "%-15s", (data[key] ? data[key] : "NA") } print "" # 换行,进入下一个文件 }' file1 file2
示例效果
假设你的file1内容是:
V 0.001 A 98.6 N Measurement1 T 14:15:01 S 20.2 F 212.86 G 28.19
file2内容是:
A 99.2 V 0.002 T 14:16:03 F 213.01 H 5.6
运行上面的脚本后,会输出这样整齐的表格:
Filename A F G H N S T V --------------------------------------------------------------------------- file1 98.6 212.86 28.19 NA Measurement1 20.2 14:15:01 0.001 file2 99.2 213.01 NA 5.6 NA NA 14:16:03 0.002
进阶优化:针对不同数据类型调整格式
如果想让数字对齐更美观(比如小数位数统一),可以给不同的键指定专属格式,比如:
awk ' BEGIN { # 自定义每个键的输出格式,按需调整 format["V"] = "%10.3f" # 保留3位小数 format["A"] = "%10.2f" # 保留2位小数 format["N"] = "%-15s" # 字符串左对齐 format["T"] = "%-12s" # 时间字符串 format["S"] = "%10.1f" format["F"] = "%10.2f" format["G"] = "%10.2f" format["H"] = "%10.1f" # 提取并排序表头键 n = 0 for(k in format) header_arr[++n] = k asort(header_arr) # 打印表头 printf "%-15s", "Filename" for(i=1;i<=n;i++) printf "%-15s", header_arr[i] print "" print "---------------------------------------------------------------------------" } { delete data for(i=1;i<=NF;i+=2) data[$i] = $(i+1) printf "%-15s", FILENAME for(i=1;i<=n;i++) { key = header_arr[i] if(data[key] != "") { printf format[key], data[key] } else { printf "%15s", "NA" } printf " " } print "" }' file1 file2
这样数字会按格式对齐,表格看起来更专业!
小提示
- 如果有很多文件,直接用
*.txt(或你的文件后缀)代替file1 file2就能批量处理 - 列宽和格式可以根据你的实际数据长度调整,比如把
%-15s改成%-20s来容纳更长的字符串
内容的提问来源于stack exchange,提问作者iSwimInTheC
相关产品推荐
相关产品推荐

