【发布时间】:2013-12-28 19:34:49
【问题描述】:
我有一组数据文件(例如,“data####.dat”,其中 #### = 0001,...,9999),它们都具有相同的 x 数据结构- 第一列中的值,然后是具有不同 y 值的多个列。
data0001.dat:
#A < comment line with unique identifier 'A'
#B1 < this is a comment line that can/should be dropped
1 11 21
2 12 22
3 13 23
data0002.dat:
#A < comment line with unique identifier 'A'
#B2 < this is a comment line that can/should be dropped
1 13 23
2 12 22
3 11 21
它们基本上源自我的程序的不同运行,具有不同的种子,我现在想将这些部分结果组合成一个公共直方图,以便保留以“#A”(所有文件都相同)开头的注释行,而其他注释行被删除。第一列保持不变,然后所有其他列应在所有数据文件上进行平均:
dataComb.dat:
#A < comment line with unique identifier 'A'
1 12 22
2 12 22
3 12 22
12 = (11+13)/2 = (12+12)/2 = (13+11)/2 和 22 = (21+23)/2 = (22+22)/2 = (23+21)/2 的位置
我已经有一个 bash 脚本(可能是可怕的代码;但我不是很有经验...),它通过在命令行中运行 ./merge.sh data* > dataComb.dat 来完成这项工作。它还会检查所有数据文件是否具有相同的列数和第一列中的相同值。
merge.sh:
#!/bin/bash
if [ $# -lt 2 ]; then
echo "at least two files please"
exit 1;
fi
i=1
for file in "$@"; do
cols[$i]=$(awk '
BEGIN {cols=0}
$1 !~ /^#/ {
if (cols==0) {cols=NF}
else {
if (cols!=NF) {cols=-1}
}
}
END {print cols}
' ${file})
i=$((${i}+1))
done
ncol=${cols[1]}
for i in ${cols[@]}; do
if [ $i -ne $ncol ]; then
echo "mismatch in the number of columns"
exit 1
fi
done
echo "#combined $# files"
grep "^#A" $1
paste "$@" | awk "
\$1 !~ /^#/ && NF>0 {
flag=0
x=\$1
for (c=1; c<${ncol}; c++) { y[c]=0. }
i=1
while (i <= NF) {
if (\$i==x) {
for (c=1; c<${ncol}; c++) { y[c] += \$(i+c) }
i+= ${ncol}
} else { flag=1; i=NF+1; }
}
if (flag==0) {
printf(\"%e \", x)
for (c=1; c<${ncol}; c++) { printf(\"%e \", y[c]/$#) }
printf(\"\n\")
} else { printf(\"# x -coordinate mismatch\n\") }
}"
exit 0
我的问题是,对于大量数据文件,它会很快变慢,并且有时会引发“打开的文件过多”错误。我看到一次性粘贴所有数据文件 (paste "$@") 是这里的问题,但是分批进行并以某种方式引入临时文件似乎也不是理想的解决方案。我将不胜感激任何帮助以使其更具可扩展性,同时保留调用脚本的方式,即所有数据文件作为命令行参数传递
我决定也将其发布在 python 部分,因为我经常被告知处理此类问题非常方便。然而,我几乎没有使用 python 的经验,但也许这是最终开始学习它的机会;)
【问题讨论】: