0.おめでとうございます。 gawkでバグを見つけたようです。

0.おめでとうございます。 gawkでバグを見つけたようです。

FPAT 正規表現で NF を使用すると、カンマがフィールドとして扱われます。私はNFとFPATを使用することを好みます。

1) NF - レコードの実際のフィールド数に出力を制限します。

2)FPAT - 行3などの引用符付きフィールドに含まれるコンマを処理します。

 "Bus Driver, City/Transit",51

3)異なる列数のレコード6を持つ複数の入力ファイルのawkスクリプト - レコード6はファイルの内容の列名/タイトルです。

テストの出力である最初のtest1は固定値をフィールド数として使用し、2番目のtest2はNFをフィールド数として使用します。

gawk 4.1.4の使用

    BEGIN {
            FPAT = "(^,)|([^,]+)|(\"[^\"]+\")"
            OFS = "\t"
        }

    NR == 6 {

       for (i = 1; 6 >= i; ++i) {
       #for (i = 1; NF >= i; ++i) {

           colName[i] = $i
           print "Column Name: " colName[i]

    }    

      { print "", "number of fields: " NF }
    }

入力ファイルはレコード6から始まります:NR == 6 {...

    Occupation,States Licensed 
    Barber,51 
    "Bus Driver, City/Transit",51

私の期待/望む結果:

    Column Name: Occupation
    Column Name: States Licensed
        number of fields: 2

テスト 1: for (i = 1; 6 >= i; ++i) {...

出力は正確です。もちろん、無効であるが固定値6を使用して表示される4つの列/フィールドを除いて、私が予想/望んでいました。

    Column Name: Occupation
    Column Name: States Licensed
    Column Name: 
    Column Name: 
    Column Name: 
    Column Name: 
        number of fields: 2

テスト 2: for (i = 1; NF >= i; ++i) {...

出力は私が期待したいと思ったものとは異なります。カンマはフィールドを表します。

    Column Name: Occupation
    Column Name: ,
    Column Name: States Licensed
        number of fields: 3

答え1

0.おめでとうございます。 gawkでバグを見つけたようです。

私はこれを非常に小さな例に縮小しました。 (より単純な文字列で欠陥を説明することもできますが、さらにFPAT10分を費やしたくありませんでした。)デフォルトでは、これらの入力に対してfoo,bar2つの異なる結果が得られます。

最初のケース:

NF = 2
$1 = foo
$2 = bar
$3 =

そして

ケースB:

NF = 3
$1 = foo
$2 = ,
$3 = bar

このコードはケースB:

BEGIN {
        FPAT = "^,|[^,]+"
}

{
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

(括弧は不要なので削除しましたFPAT。カンマを含む可能性のある引用文字列を処理する正規表現部分を削除し、コードを最小限に抑えました。)

使用

エコフー、バー|awk_script 上記の名前

しかし - 少なくとも gawk バージョン 4.1.1 では -$1アクセスする前にアクセスすると、NF次のようになります。ケース A.  ステートメントの順序を変更しprintたり、次のような不可解な組み合わせでこれを証明したりできます。

{
        temp = $1                       # We will never use this.
        print "NF =", NF
        print "$1 =", $1; print "$2 =", $2; print "$3 =", $3
}

これは明らかに不可能な間違いです。入場フィールドは他のものの値を変更する必要があります。 

1. だから私たちには解決策があります。

temp = $1ループの前に追加するとfor(使用して)目的の結果が得られることを願っています  NF

2. 本当(?) 答えは:

上記では、A事例やB事例を「正しい」、「そうだ」と呼ぶことをわざわざ避けました。状況Aはあなたが望む状況ですが、状況Bは実際にあなたが望む状況かもしれません。正しいFPAT結果は使用中の値です。これはあなたがフィールドが欲しいと言うようです

  • カンマで始まる文字列、または
  • カンマ以外の1つ以上の文字で構成される文字列、または
  • 引用符、1 つ以上の引用符ではなく文字で構成される文字列、およびその他の引用符。

ただし、カンマがフィールドになることは望ましくありません。 2番目と3番目のオプションのみが必要です。その設定が見つかりました。

FPAT = "[^,]+|\"[^\"]+\""

正しい結果を与えます。

関連情報