4

時系列のファイル 0000.vx.dat、0000.vy.dat、0000.vz.dat があります。...; 0077.vx.dat、0077.vy.dat、0077.vz.dat... 各ファイルは、スペースで区切られた 2D マトリックスです。ファイルの各トリプレットを取得し、それらをすべて座標ベースのデータ形式に結合したいと思います。

[タイムステップ + 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 を $ を前に付けたシェル変数形式のままにしていたことを指摘してくれてありがとう! これは元のスクリプトのスニペットにすぎませんが、その根性と見なされると思います!

O(MxN) アルゴリズム、サブシェル、パイプなどに関連する bash のすべてのメモリ オーバーヘッドのため、これには約 6 か月かかると言えば十分でしょう。私はせいぜい一日のラインに沿ってもっと探していました。各ファイルは約 18 MB であるため、それほど問題にはなりません。タイムステップごとに 1 つの出力ファイルを取得するという条件で、awk で一度に 1 つのタイムステップを実行できれば幸いです。あとがきはあまり問題なく、それらをすべて一緒に猫にすることができたと思います。ただし、時間ステップ番号が座標リストの最初の項目であることが重要です。これは、bash ルーチンで awk -v 引数 (上記を参照) を使用して実現できます。行列の特定の要素を 3 つの個別のファイルで検索し、それらをすべて 1 つの出力にまとめる方法がわかりません。これは私が克服したい主なハードルです。私は、mawk が労力と計算速度のバランスをうまくとれることを望んでいました。これがawkスクリプトには多すぎると思われる場合は、より低いレベルに進むことができ、代わりにCに行くべきだと教えてくれる回答者に感謝します。

前もって感謝します!私はawkが本当に好きですが、初心者なので心配です。

0000.vx.dat、0000.vy.dat、および 0000.vz.dat の 3 つのファイルは、次のようになります (巨大で正しいサイズを除く)。

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

編集:シェルター、希望する入力と出力をより明確にすることを提案してくれてありがとう!

4

1 に答える 1

2

個人的には、gawkほとんどのテキスト ファイルを処理するために使用しています。ただし、mawk互換性のあるソリューションをリクエストしたため、問題を解決する 1 つの方法があります。現在の作業ディレクトリで実行します。

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)
    }
}

上記を実行すると、結果は、座標を含む 3 つのファイルのセットごとに 1 つのファイルになります。これらの出力ファイルのファイル名は、タイムスタンプ + 1 ".dat" の形式になります。便宜上、これらのファイル名に 4 つの 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 に答える