TT Lab
はじめる
学ぶ 学習パス コース

システム間連携 (EAI)

固定長ファイルインターフェースのパースと照合

TT Labで続きを見る

目標

固定長電文のファイルをレイアウトどおりにパースし、トレーラーで完全性を検証し、エンコーディング変換・完了フラグ・保管・突合まで、ファイルインターフェースの1サイクルを完成させます。

なぜ重要なのか

ファイル連携は古く見えますが、大量処理と突合のしやすさでは、今も最善です。問題は、失敗の仕方が静かなことです。送信中に切れたファイルをそのまま処理すると、エラーなしに半分だけ反映され、その事実は、月末の締めに「数字が合わない」として発見されます。完了フラグの規約が片方にしかないと、バッチが毎日何も処理せず、何のエラーも出しません。静かに何もしないことが、最も遅く発見されます。トレーラーの検証と突合は、その静かな失敗を、騒がしくするための仕組みです。

ステップ

  1. /opt/lab/fixtures/eai/file/layout.mdを読んで、/root/f/layout.csvを作成してください。1行目はseq,field,start,length,typeです。 startは1から始まる位置で、seqの順に並べ替えます。
  2. /root/f/parse.shを作成してください。引数を1つ(データファイル)受け取り、Dで始まるデータレコードだけを、次の6つのフィールドをパイプ(|)で区切って出力します。
    SALE_DT|CUST_ID|CUST_NM|PROD_CD|QTY|AMT
    
    文字フィールドの前後の空白は除去し、数値フィールドの先頭の0も除去します。(REC_TYPEは出力しません。) /opt/lab/fixtures/eai/file/SALES_20260801.datで実行した結果を、/root/f/parsed.txtに保存してください。
  3. /root/f/verify.shを作成してください。引数を1つ(データファイル)受け取り、トレーラーの件数と金額合計がデータレコードと一致すれば終了コード0、不一致なら1行目に理由を出力して、0以外の終了コードで終了します。
    • SALES_20260801.dat → 通過する必要があります
    • SALES_20260802.dat → 失敗する必要があります
  4. /opt/lab/fixtures/eai/file/SALES_EUCKR.datをUTF-8に変換して、/root/f/SALES_utf8.datに保存してください。変換後、ハングルが正常に読める必要があります。
  5. /root/f/pick.shを作成してください。引数を1つ(ディレクトリ)受け取り、.okフラグファイルが一緒にある.datのファイル名だけを、1行に1つずつ出力します。.okファイル自体は出力しません。
  6. /root/f/csvcheck.pyを作成してください。引数を1つ(CSVファイル)受け取り、rows=<데이터 행수> fields=<헤더 필드수> bad=<필드수가 다른 행수>(プレースホルダーは、順にデータの行数、ヘッダーのフィールド数、フィールド数が異なる行数です)を1行で出力します。引用符の中のカンマ・改行を正しく処理する必要があります。 /opt/lab/fixtures/eai/file/orders_quoted.csvで実行した結果を、/root/f/csvcheck.txtに保存してください。
  7. SALES_20260801.datを/root/f/archive/20260801/の下に、gzipで圧縮して保管してください。元のファイル名に.gzが付いた形である必要があります。
  8. /root/f/recon.csvを作成してください。1行目はitem,source,target,diff,resultです。 /opt/lab/fixtures/eai/file/SALES_20260801.dat(source)と/opt/lab/fixtures/eai/file/SALES_20260801.csv(target)を比較して、countの行とamountの行の2つを埋めます。 resultは、一致すればOK、異なればNGです。

参考

レイアウト定義の整理

/opt/lab/fixtures/eai/file/layout.mdを読んで、/root/f/layout.csvを作成してください。 1行目はseq,field,start,length,typeです。 startは1から始まる位置で、seqの順に並べ替えます。

開始位置は1から数えます。前のフィールドの長さの合計に1を足すと、次のフィールドの開始位置です。最後のフィールドの終わりが、レコード全体の長さと合うかを検算してください。

固定長パーサー

/root/f/parse.shを作成してください。引数を1つ(データファイル)受け取り、Dで始まるデータレコードだけを、次の6つのフィールドをパイプ(|)で区切って出力します。

SALE_DT|CUST_ID|CUST_NM|PROD_CD|QTY|AMT

文字フィールドの前後の空白は除去し、数値フィールドの先頭の0も除去します。(REC_TYPEは出力しません。) /opt/lab/fixtures/eai/file/SALES_20260801.datで実行した結果を、/root/f/parsed.txtに保存してください。

cutは、バイト基準の-bと文字基準の-cが違います。ハングルが混ざると、この違いが結果を変えます。数値フィールドの先頭の0をどう処理するかも、決める必要があります。

トレーラーの検証

/root/f/verify.shを作成してください。引数を1つ(データファイル)受け取り、トレーラーの件数と金額合計がデータレコードと一致すれば終了コード0、不一致なら1行目に理由を出力して、0以外の終了コードで終了します。

検証は、処理の前に行う必要があります。処理中に行うと、すでに半分が反映された状態になります。件数と合計の両方を見る必要があります。

エンコーディング変換

/opt/lab/fixtures/eai/file/SALES_EUCKR.datをUTF-8に変換して、/root/f/SALES_utf8.datに保存してください。変換後、ハングルが正常に読める必要があります。

受け取ったファイルが文字化けして見えたら、まずエンコーディングを疑います。韓国の対外連携では、ハングルが2バイトになるエンコーディングが、今も使われています。

完了フラグによる選別

/root/f/pick.shを作成してください。引数を1つ(ディレクトリ)受け取り、.okフラグファイルが一緒にある.datのファイル名だけを、1行に1つずつ出力します。 .okファイル自体は出力しません。

フラグのないファイルは、まだ送信中かもしれません。引数でディレクトリを受け取って、処理対象だけを出力するようにしてください。

CSVインターフェースの検証

/root/f/csvcheck.pyを作成してください。引数を1つ(CSVファイル)受け取り、rows=<데이터 행수> fields=<헤더 필드수> bad=<필드수가 다른 행수>(プレースホルダーは、順にデータの行数、ヘッダーのフィールド数、フィールド数が異なる行数です)を1行で出力します。 引用符の中のカンマ・改行を正しく処理する必要があります。 /opt/lab/fixtures/eai/file/orders_quoted.csvで実行した結果を、/root/f/csvcheck.txtに保存してください。

CSVは、引用符の中にカンマと改行が入ることがあります。単純な分割では、フィールド数が間違います。標準のパーサーを使ってください。

処理後の保管

SALES_20260801.datを/root/f/archive/20260801/の下に、gzipで圧縮して保管してください。元のファイル名に.gzが付いた形である必要があります。

日付別のディレクトリに分けて初めて、1つのディレクトリにファイルが数十万個溜まるのを防げます。テキストは圧縮効果が大きいです。

突合表の作成

/root/f/recon.csvを作成してください。1行目はitem,source,target,diff,resultです。 /opt/lab/fixtures/eai/file/SALES_20260801.dat(source)と/opt/lab/fixtures/eai/file/SALES_20260801.csv(target)を比較して、countの行とamountの行の2つを埋めます。 resultは、一致すればOK、異なればNGです。

件数だけが合えば安心しやすいですが、1件が抜けて別の1件が2回入っても、件数は合います。合計も一緒に見てください。