Record_count
詳細レコード全体がトレーラーレコードと同じであることを確認し、一致しない場合はエラーを発生させるスクリプトを作成しようとしています。
サンプル:
HDR9185 20210601094001202105311.11j
DTL226-42742-14 32.389185 NM30100000178103 D207935784ZAG Desjardins Trust CAD 5470.34 32.38A E 2.0500 5549.4420220215NESBITT BURNS INC A/C 226-42742-14 (5H94798) C 5014.0020170215N30100000178103 5H94798 ILPYA7SM71
DTL210-86993-11 21.979185 NM30100000187369 D207989578ZAG Desjardins Trust CAD 5036.97 21.97N A 2.0500 5117.8120220315NESBITT BURNS INC ITF A/C 210-86993-11 (5J10948) C 5015.0020170315N30100000187369 5J10948 ILQETLZDH1
TRL 02 93084.00
トレーラーレコードは02
レコード番号です。
私のコード:
if ! awk -F "|" ' /^HDR/ { h++; next; } /^TRL/ {t++; next} END { exit( (h != 1) || t != 1 || $NF != NR - 2 ); }' sample.txt
then
echo "file did not pass validation test"
exit 1
fi
echo "Validated successfully"
私の履歴がトレーラーの数と一致するか一致しない場合でも、「ファイル検証テストの失敗」という標準出力が発生します。
答え1
あなたのコードでは、データが|
フィールド区切り文字として使用されると仮定しているようですが、そうではありません。あると主張したいようです。一つヘッダーレコード(HDR...
)と一つtail Record( TRL
) および tail レコードは、正しい数値、つまり中間データ records() の数を指しますDTL...
。
ファイルに空白行が含まれる可能性があるため、無視する必要があるとします。
プログラムawk
:
$1 ~ /^HDR/ { h++ }
$1 ~ /^DTL/ { d++ }
$1 == "TRL" { t++; ok = (d == $2) }
END { exit !(h == 1 && t == 1 && ok) }
各HDR...
レコードに対してh
増加します。各DTL...
レコードに対してd
増加します。TRL
レコードが見つかると、データ行数が正しいかどうかを示すt
ブール値を増やして計算します。ok
END
ヘッダーとトレーラーレコードが偶然見つかり、ブールok
値が次の場合本物。
次のコードは、レコードが順序が正しくない場合(ゼロデータレコードを許可している間)、ゼロ以外の終了状態で終了します。
BEGIN { ok = 1 }
$1 ~ /^HDR/ { h++; ok = (h == 1 && d == 0 && t == 0) }
$1 ~ /^DTL/ { d++; ok = (h == 1 && t == 0) }
$1 == "TRL" { t++; ok = (h == 1 && d == $2 && t == 1) }
!ok { exit }
END { exit !(h == 1 && t == 1 && ok) }
これはブール変数内のデータの完全な有効性を維持しok
、その変数がロールオーバーされたときにゼロ以外の終了状態で終了します。間違った(またはまだ存在する場合、終了ステータス0本物完全なコード実行プロセス)。ブロックに到達するときは、正確に1つのヘッドレコードとテールレコードが表示されていることを確認する必要がありますEND
。それ以外の場合は、空のファイルが正しいことを確認してください。
上記のawk
プログラムのいずれかを実行するには、ファイル(ここにvalidate.awk
)に入れて、以下を使用してください。
if awk -f validate.awk sample.txt; then
echo 'file ok'
else
echo 'file not validated'
fi
または、コマンドラインからプログラム全体を一重引用符で囲んだ文字列として提供します。
if awk '$1 ~ /^HDR/ { h++ } $1 ~ /^DTL/ { d++ } $1 == "TRL" { t++; ok = (d == $2) } END { exit !(h == 1 && t == 1 && ok) }' sample.txt
then
echo 'file ok'
else
echo 'file not validated'
fi
アドレス指定コメントレコードにすべての種類のレコード数があるようにTRL
見えるとします。TRL0009 93084.00
0009
この場合、最初のawk
プログラムは次のようになります。
$1 ~ /^HDR/ { h++ }
$1 ~ /^DTL/ { d++ }
$1 ~ /^TRL/ { t++; ok = ( d == substr($0,4,4) - 2 ) }
END { exit !(h == 1 && t == 1 && ok) }
ここでは、(元の入力行)の位置4から始まり、長さ4の文字列をsubstr($0,4,4)
選択します。$0
ヘッドレコードとテールレコードを計算するには、この数字から2を減算します。
答え2
おそらく:
if awk -v RS='' '$1 == "TRL" {exit !($2 == (NR - 2))}' file; then
echo "success"
else
echo "invalid"
fi
awkのRS = ""
意味は、各レコードが空の行(「ショートモード」とも呼ばれる)で区切られていることです。
私は最初にその声明の説明を持っていました。
exit !($2 == (NR - 2))
しかし、あなたの質問に似たコードがあるので、大丈夫だとします。それでも:
- トレーラーレコード数を有効にするには、ファイル全体にその数とヘッダーとトレーラーを正確に含める必要があります。
- ファイル全体のレコード数は awk NR 変数です。
- マイナス2は予告編のカウントでなければなりません。
- Cと同様に、算術比較演算子は成功した場合は1を返し、失敗した場合は0を返します。
- シェルは終了状態をゼロとみなして成功を示し、ゼロでない場合は失敗を示します。
==
だから私たちは演算子の戻りコードを無効にします。
私のコードが表示されるレコードを考慮していないことに気づきました。後ろに予告編があると、ファイルが無効になることがあります。試してみてください。
if awk -v RS='' '$1 == "TRL" {n = $2} END {exit !(n == NR - 2)}' file; then ...