如何转置gnuplot可读文件中的数据块(表格)
如何转置文件中的多个数据块?
数据块规则:每个数据块以# description行开头,以两个空行结尾。
输入示例
# block_01 Temp ST_01 ST_02 ST_03 ST_04 ag7 -0.0295167 0.0553285 0.00883727 0.392553 bc9 -0.0513702 0.0355596 -0.0165404 0.252816 cc9 -0.0303508 -0.00354388 0.0428582 0.0882037 cd3 -0.0239757 -0.0363891 0.0227775 0.270722 # block_02 Temp ST_01 ST_02 ST_03 ST_04 ag7.b -0.00284193 0.0260536 0.163357 -0.17291 bc9.b -0.0212977 0.0191269 0.0330521 -0.17346 cc9.b -0.0138837 -0.0220729 0.0814398 -0.0478094 cd3.f -0.053152 -0.0041982 -0.0948933 -0.020557 # block_03 Temp ST_01 ST_02 ST_03 ST_04 ...
期望输出
# block_01 Temp ag7 bc9 cc9 cd3 ST_01 -0.0295167 -0.0513702 -0.0303508 -0.0239757 ST_02 0.0553285 0.0355596 -0.00354388 -0.0363891 ST_03 0.00883727 -0.0165404 0.0428582 0.0227775 ST_04 0.392553 0.252816 0.0882037 0.270722 # block_02 Temp ag7.b bc9.b cc9.b cd3.f ST_01 -0.00284193 -0.0212977 -0.0138837 -0.053152 ST_02 0.0260536 0.0191269 -0.0220729 -0.0041982 ST_03 0.163357 0.0330521 0.0814398 -0.0948933 ST_04 -0.17291 -0.17346 -0.0478094 -0.020557 # block_03 Temp ag7.b bc9.b cc9.b cd3.f ...
解决方案
1. 使用Awk脚本
这个脚本会逐个处理每个数据块,收集字段后转置输出:
#!/usr/bin/awk -f /^#/ { if (block_lines > 0) { print_block() } print $0 block_lines = 0 next } /^$/ { empty_lines++ if (empty_lines == 2) { print_block() empty_lines = 0 print "\n" } next } { empty_lines = 0 for (i=1; i<=NF; i++) { fields[block_lines+1][i] = $i } block_lines++ } END { if (block_lines > 0) { print_block() } } function print_block() { if (block_lines == 0) return cols = length(fields[1]) for (c=1; c<=cols; c++) { line = fields[1][c] for (r=2; r<=block_lines; r++) { line = line "\t" fields[r][c] } print line } delete fields }
使用步骤:
- 保存脚本为
transpose_blocks.awk - 赋予执行权限:
chmod +x transpose_blocks.awk - 运行处理文件:
./transpose_blocks.awk input.txt > output.txt
2. 使用Bash结合GNU工具
通过拆分块、单独转置再合并的方式实现:
#!/bin/bash input_file="$1" temp_dir=$(mktemp -d) # 拆分输入文件为单个块的临时文件 awk ' /^#/ { if (outfile != "") close(outfile) block_num++ outfile = sprintf("%s/block_%02d", temp_dir, block_num) print > outfile next } /^$/ { empty_lines++ if (empty_lines == 2) { close(outfile) empty_lines = 0 outfile = "" } else if (outfile != "") { print > outfile } next } { empty_lines = 0 if (outfile != "") print > outfile } ' "$input_file" # 处理每个临时块并输出 for block in "$temp_dir"/block_*; do head -n1 "$block" tail -n+2 "$block" | awk '{for(i=1;i<=NF;i++)a[i]=a[i]"\t"$i}END{for(i in a)print substr(a[i],2)}' echo -e "\n" done | sed '$ s/\n$//' rm -rf "$temp_dir"
使用步骤:
- 保存脚本为
transpose_blocks.sh - 赋予执行权限:
chmod +x transpose_blocks.sh - 运行处理文件:
./transpose_blocks.sh input.txt > output.txt
内容的提问来源于stack exchange,提问作者magfan
相关产品推荐
相关产品推荐

