CSV转TXT、偶数统计及数值批量缩放的Shell实现优化咨询
传感器数据处理优化方案
背景
我有一份传感器XaB.v2的记录文件data.csv,内容示例如下:
# Recorded data from sensor XaB.v2 # Recording started on Oct 29 15:00:00 # Recording ended on Oct 29 15:15:59 # X, Y, Z, X', Y', Z' 55, 14, 48, 62, 78, 41 32, 52, 94, 11, 17, 83
需要完成两个任务:将CSV转成TXT文件并统计其中偶数数量;生成该TXT文件的n个副本,每个副本内的数值都除以i(i从1到n)。以下是现有实现的优化建议:
1. CSV转TXT与偶数统计优化
现有实现的问题
现有命令分两步处理,不仅多生成了中间文件,grep+sed的组合也可以简化,整体效率有提升空间:
grep -v '^#' data.csv | sed -e 's/,//g' > data.txt grep -o '[0-9]\+' data.txt | awk '$1%2 == 0' | wc -l
优化方案
方案1:简化转TXT命令
用awk一步完成注释过滤与逗号清除,替代grep+sed的组合,逻辑更紧凑:
awk '!/^#/{gsub(/,/, ""); print}' data.csv > data.txt
方案2:跳过中间文件,直接统计偶数
如果不需要保留data.txt,可以直接从原CSV文件统计,省去磁盘IO操作:
awk '!/^#/{FS=", "; for(i=1;i<=NF;i++) if($i%2==0) count++} END{print count}' data.csv
- 用
,作为字段分隔符,直接提取每个数值 - 遍历所有字段统计偶数数量,最后输出结果
2. 生成缩放副本脚本优化
现有脚本的问题
现有脚本缺少必要的参数校验(比如n是否为正整数、是否传入参数),且输出的数值会无间隔连在一起,可读性差:
n=$1 for ((i=1; i<=n; i++)) do awk -v divisor="$i" '{ for (j=1; j<=NF; j++) printf "%.6f", $j / divisor; print "" }' data.txt > "data_${i}.txt" done
优化后的脚本
添加参数校验逻辑,同时优化awk的输出格式(数值间用空格分隔),让脚本更健壮清晰:
#!/bin/bash # 参数校验:必须传入一个正整数 if [ $# -ne 1 ] || ! [[ $1 =~ ^[1-9][0-9]*$ ]]; then echo "错误:请提供一个正整数作为参数" exit 1 fi n=$1 for ((i=1; i<=n; i++)); do # 替换每个字段为除以i后的格式化值,自动用空格分隔 awk -v divisor="$i" '{ for(j=1; j<=NF; j++) { $j = sprintf("%.6f", $j / divisor) } print }' data.txt > "data_${i}.txt" done
- 先做参数校验:检查是否只传入一个参数,且参数是正整数(排除0和非数字输入)
awk部分直接修改每个字段的值,打印整行时自动用空格分隔数值,比逐个printf更简洁- 输出文件命名保持原逻辑:
data_1.txt到data_n.txt
内容的提问来源于stack exchange,提问作者taschi87
相关产品推荐
相关产品推荐

