日付に基づいてファイルを分割し、合計と金額を含む予告編を追加します。

日付に基づいてファイルを分割し、合計と金額を含む予告編を追加します。

ソースファイル:

  • タイトルは次から始まります。H
  • 予告編は次のように始まります。T
  • R で始まるレコード
  • 区切り記号は次のとおりです。|~^

入力ファイルのサンプル

  • R で始まる入力レコードには、ソースソースファイルに複数のフィールドがあります。ここでは、例では5つのフィールドしか言及していません。

  • トレーラーレコードの3番目の列はレコード数で、5番目の列は金額列(レコードの3番目の列または行)の合計です。

  • 分割後のトレーラーは、数と合計の列を含む次の形式で新しいファイルに追加する必要があります。

  • R で始まる INPUT レコードは日付順に従わない。たとえば、最初のレコードは2019-03-05として記録され、最後のレコードも同じ日付です。

メモ:

  • R で始まる INPUT レコードには複数の列の日付フィールドが含まれるため、3 番目の日付フィールドを分割することをお勧めします。

  • またお願いします日付フィールドのタイムスタンプを無視;日付のみを考慮し、日付のみに基づいて分割を実行できます。理想的には、3列目の同じ日付のすべての取引を新しいファイルに移動し、合計と数が追加されたヘッダー/トレーラーに移動する必要があります。 ****編集********私の質問はまだ同じですが、金額フィールドが非常に大きい数値である場合(金額フィールドデータ型は小数点が最大5点、毎回(31,5)ではありませんが、小数点以下5桁の金額がある場合、最大小数点5桁までの値が適用されます。)

入力ファイル:

H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^8|~^xxx|~^123670130.37256

期待される出力

ファイル1:次の名前で保存する必要があります。20190305.txt

H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^4|~^xxx|~^107707.068

ファイル2:次の名前で保存する必要があります。20190306.txt

H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
T|~^20200425|~^4|~^xxx|~^123562423.30456

ベストアンサー1

最後の編集で質問全体を変更しました。

各行に対してタイムスタンプをファイル名に変換する必要があります。からまで
です。これだけでかなりの文字列処理が必要で、これはどの言語でもそれほど高速ではありません。2019-03-06T12:33:52.2720190306

この小さな部分はawkで行うことができます。

awk 'BEGIN{FS="\\|~\\^";OFS="|~^"}
     $1=="R"{
              t=gensub(/-/, "","g",$3)
              s=gensub(/T.*/,"",1,t);
              $3=s
            }
     1
' "file" >"file.adj"

その後、タイムスタンプの日付(元の問題)に基づいてファイルがまだ分割されます。必要な最小変更のリストは次のとおりです。

  • 入力の各行を指定されたファイル($3として提供)にコピーします。
  • 完了したら(各ファイルに対して)行数を計算します。
  • そしてフィールドの値を合計します4
  • すべての入力行が処理された後、尾を各ファイルに印刷します。

全体のプロセスは、次のようにawkで実行できます。

awk 'BEGIN  { FS="\\|~\\^"; OFS="|~^" }
     $1=="H"{ header=$0; hdr=$2 }
     $1=="R"{
              t=gensub(/-/, "","g",$3)
              file=gensub(/T.*/,"",1,t);
              sum[file]+=$4
              if(count[file]==0){ print header >file }
              count[file]++
              print $0 >>file
            }
     END    {
              for( i in sum ){
                  print "T",hdr,count[i],"xxx",sum[i] >> i;
                  close(i)
                  }
            }
' "file"

Perlを使用してソースファイルを100万回繰り返すと、ファイル全体がわずか49.32秒で処理されました。最小メモリ使用量(1日の合計と数をメモリに保持するだけです)これは私にとってかなり速いようです。

おすすめ記事