4

我有一个时间序列的文件 0000.vx.dat、0000.vy.dat、0000.vz.dat;...; 0077.vx.dat, 0077.vy.dat, 0077.vz.dat... 每个文件都是一个空格分隔的二维矩阵。我想获取每个三元组文件并将它们全部组合成基于坐标的数据格式,即:

[时间步长 + 1] [i] [j] [vx(i,j)] [vy(i,j)] [vz(i,j)]

每个文件编号对应一个特定的时间步长。鉴于我在这个时间序列中拥有的数据量(~ 4 GB),bash 并没有削减它,所以似乎是时候转向 awk 了……特别是 mawk。在 bash 中尝试这个非常愚蠢,但这是我命运多舛的尝试:

for x in $(seq 1 78)
do
  tfx=${tf[$x]} # an array of padded zeros
  for y in $(seq 1 1568)
  do
    for z in $(seq 1 1344)
    do
      echo $x $y $z $(awk -v i=$z -v j=$y "FNR == i {print j}" $tfx.vx.dat) $(awk -v i=$z -v j=$y "FNR == i {print j}" $tfx.vy.dat) $(awk -v i=$z -v j=$y "FNR == i {print j}" $tfx.vz.dat) >> $file
    done
  done
done

编辑:谢谢你,ruakh,指出我把 j 保存在 shell 变量格式中,前面有一个 $!这只是原始脚本的一个片段,但我想会被认为是它的胆量!

可以说这需要大约六个月的时间,因为 bash 中的所有内存开销都与 O(MxN) 算法、子外壳和管道等相关联。我最多在一天内寻找更多。每个文件大约 18 MB,所以应该不是什么大问题。如果我在每个时间步得到一个输出文件,我会很高兴在 awk 中一次执行一个时间步。我想我可以把它们全部放在一起,没有太多的后记问题。但重要的是,时间步数是坐标列表中的第一项。我可以通过 bash 例程中的 awk -v 参数(见上文)来实现这一点。我不知道如何在三个单独的文件中查找矩阵的特定元素并将它们全部放在一个输出中。这是我想克服的主要障碍。我希望 mawk 可以在工作量和计算速度之间提供一个很好的平衡。如果这对于 awk 脚本来说似乎太过分了,我可以转到较低级别的内容,并且会感谢任何回答让我知道我应该改为使用 C 的人。

先感谢您!我真的很喜欢awk,但我怕我是新手。

这三个文件 0000.vx.dat、0000.vy.dat 和 0000.vz.dat 的内容如下(巨大且尺寸正确的除外):

0000.vx.dat:

1 2 3
4 5 6
7 8 9

0000.vy.dat:

10 11 12
13 14 15
16 17 18

0000.vz.dat:

19 20 21
22 23 24
25 26 27

我希望能够输入:

awk -v t=1 -f stackoverflow.awk 0000.vx.dat 0000.vy.dat 0000.vz.dat

并获得以下输出:

1 1 1 1 10 19
1 1 2 2 11 20
1 1 3 3 12 21
1 2 1 4 13 22
1 2 2 5 14 23
1 2 3 6 15 24
1 3 1 7 16 25
1 3 2 8 17 26
1 3 3 9 18 27

编辑:谢谢你,shellter,建议我更清楚地输入所需的输入和输出!

4

1 回答 1

2

就个人而言,我gawk用来处理我的大部分文本文件。但是,由于您已请求mawk兼容的解决方案,因此这是解决问题的一种方法。在您当前的工作目录中运行:

for i in *.vx.dat; do nawk -f script.awk "$i" "${i%%.*}.vy.dat" "${i%%.*}.vz.dat"; done

内容script.awk

FNR==1 {
    FILENAME++
    c=0
}

{
    for (i=1;i<=NF;i++) {
        c++
        a[c] = (a[c] ? a[c] : FILENAME FS NR FS i) FS $i
    }
}

END {
    for (j=1;j<=c;j++) {
        print a[j] > sprintf("%04d.dat", FILENAME)
    }
}

当您运行上述程序时,结果应该是每个包含您的坐标的三个文件的单个文件。这些输出文件的文件名格式为:timestamp + 1 ".dat"。为了方便起见,我决定用四个 0 填充这些文件名。但是您可以将其更改为您喜欢的任何格式。这是我从您发布的示例数据中得到的结果。内容0001.dat

1 1 1 1 10 19
1 1 2 2 11 20
1 1 3 3 12 21
1 2 1 4 13 22
1 2 2 5 14 23
1 2 3 6 15 24
1 3 1 7 16 25
1 3 2 8 17 26
1 3 3 9 18 27
于 2013-01-29T06:15:17.590 回答