AWKのレコード計算に問題があります。

AWKのレコード計算に問題があります。

こんにちは、長さに問題があるレコード数を数えるawk式があります。問題は、エラーがない場合、私のカウントがゼロではないことです。

パスワード

err_count=$(
    awk -v m=1 -v p=5 -v count=0 '
        {
            c=substr($0,m,p)
            sub(" +$", "", c)
            if ( (length(c) > p) && (NR > 1) ) {
                printf "%s:%s:%s\n", FILENAME, FNR, $0 > "/dev/stderr"
                count++
            }
        }
        END {
            print count
        }
    ' /test/data/poc/BNC_fixedwidth.txt
)

入力ファイル(固定幅)

header
10027  20033t  [email protected]   19519  11/18/2021 12:06:10.260 PM BNC HardB 5 User Unk 125

error_count 変数は常にゼロではなく空白を提供します。誰でもライトを通して見ることができます

答え1

コードが実行された後は、このようなことを行いますが、echo "$error_count"実際に実行したい変数はありませんecho "$err_count"

答え2

cの幅が指摘するように、steeldriverそれは決してあなたの限界より長くはないでしょう:

c = substr($0, 1, 5)

長さはc5より大きくありません。

それ以外スペース/awk スクリプトに構文エラーがあるため空です。次の操作を行わない限り、これはシェルに印刷する必要があります。2>/dev/null

最新のアップデート以降は動作しなくなります。しかし、私が知っている限り、あなたはそれを修正しませんでした。明確にすべきことは次のとおりです。

    if( (length(c) >  p  && NR > 1 )
#       ^
#       +--- Never closed.

しかもあなたの編集者彼はとても呪った。\次の行でスクリプトを続行する必要はありません。それは:

  • { \しかし、{

  • いいえ

     ... "/dev/stderr"\
        ++count
    
  • しかし、

       ... "/dev/stderr"
    ++count
    

ステートメントの末尾にセミコロンを使用することは大丈夫ですが、コードを読みやすくするためにセミコロンを混在させないでください。;何らかの理由で1行に複数のステートメントがある場合を除き、すべてのステートメントの最後に使用または使用しないでください。だから:

いいえ:

    printf "%s: %d", $1, $2;
    ++foo
    ++bar;
    printf "%s: %d", $3, $4

しかし:

    printf "%s: %d", $1, $2
    ++foo
    ++bar
    printf "%s: %d", $3, $4

または(私が知っている限り広く使用されていません):

    printf "%s: %d", $1, $2;
    ++foo;
    ++bar;
    printf "%s: %d", $3, $4;

substr()$0を利用して剪定する概念でもあるsub()

awk のデフォルトの区切り文字は <space> です。これは他の文字区切り文字とは異なる方法で扱われます。つまり、複数のスペースが区切り文字で連結されます。したがって、両方の行にあります。

A B C
  A    B     C

次に続く:

$1 == A
$2 == B
$3 == C

当面の問題については、次のようにすることができます。

awk \
    -v width_max=5 \
    -v field_validate=1 \
'
BEGIN {
    err_count = 0
}
$1 == "header" {
    next
}
NF < field_validate || length($field_validate) > width_max {
    printf "%s:%d:%d:%s\n", FILENAME, NF, FNR, $0 > "/dev/stderr"
    ++err_count
}
END {
    printf "%d", err_count
}

' sample

NF小切手を別の小切手として受け取ることができることに注意してください。それは次のとおりです。

NF != field_count {
    # NF does not match with required fields
}

field_count定義された変数はどこにありますか?

FS、NFなどの簡単なサンプルスクリプトを確認できます。

awk -v field_count=3 \
'
NF != field_count {
    printf "NF mismatch %d != %d\n", NF, field_count
}
{
    printf "<%s><%s><%s>\n", $1, $2, $3
}
' <<EOF
AA BB CC
AA      BB    CC
   AA   BB      CC
AA BB
AA BB CC DD
EOF

関連情報