如何用Bash/awk处理原子坐标文件求指定列均值并替换对应值
解决方案
1. 替换C类原子z坐标为B类z坐标均值
直接用awk单次遍历即可实现,逻辑会自动适配每个文件中A、B、C的数量,不受前4行干扰:
awk ' NR == 2 {numA = $1; numB = $2; numC = $3} NR <= 4 {print; next} { coord_line++ # 匹配B类原子行,累加z坐标 if (coord_line > numA && coord_line <= numA + numB) { sumB += $3 countB++ } # 匹配C类原子行,替换z坐标为均值 if (coord_line > numA + numB) { avgB = countB > 0 ? sumB / countB : $3 $3 = avgB } print }' 输入文件
如需批量处理多个文件,可使用GNU awk的原地修改参数:
awk -i inplace '上述逻辑' *.txt
提前备份原文件即可批量完成所有文件的修改。
2. 替换A类原子z坐标为B类z坐标均值
需要两次遍历文件,awk原生支持同文件传入两次的写法,不需要额外传递变量:
awk ' # 第一次遍历:计算B类原子z坐标均值 FNR == NR { if (FNR == 2) { numA = $1; numB = $2 } if (FNR > 4) { coord_line++ if (coord_line > numA && coord_line <= numA + numB) { sumB += $3 countB++ } } next } # 第二次遍历:替换A类原子z坐标 { if (FNR > 4) { coord_line2++ if (coord_line2 <= numA) { avgB = countB > 0 ? sumB / countB : $3 $3 = avgB } } print }' 输入文件 输入文件
批量兼容所有awk版本的写法:
for file in *.txt; do awk '上述逻辑' "$file" "$file" > "$file.tmp" && mv "$file.tmp" "$file" done
内容的提问来源于stack exchange,提问作者Jacek
相关产品推荐
相关产品推荐

