私はawkのgawkバージョンを持っています。存在するこれgawk マニュアルの一部には、awk 変数がさまざまなタスクでどのように処理されるかを決定する「プロパティ」があることが示されています。
たとえば、" +3.14"
入力を解析して取得した形式の文字列にはこのSTRNUM
属性があるため、数値と比較すると数値として機能しますが、awkプログラムで定義されているのと同じ文字列にはこの属性はありません。
OTOH、このような文字列は、プログラムで定義されていてもコードが1を印刷するため、"3.14"
明らかに属性を持ちます。そしてorと定義すると、orは0を印刷するので属性はありません。STRNUM
x = "3.14" { print x == 3.14 }
"+3.13"
" 3.14"
STRNUM
x = "+3.14" { print x == 3.14 }
x = " 3.14" { print x == 3.14 }
変数型のこの単純さは微妙なバグにつながる可能性があると思います。それでは、この状況をデバッグするのに役立つように、変数にどのような「属性」があるかを知る方法はありますか?つまり、変数の型が何であるかを知ることができますか?
ベストアンサー1
awkは4種:「数字」、「文字列」、「数字 - 文字列」、および「未定義」。これは機能検出済み:
function o_class(obj, q, x, z) {
q = CONVFMT
CONVFMT = "% g"
split(" " obj "\1" obj, x, "\1")
x[1] = obj == x[1]
x[2] = obj == x[2]
x[3] = obj == 0
x[4] = obj "" == +obj
CONVFMT = q
z["0001"] = z["1101"] = z["1111"] = "number"
z["0100"] = z["0101"] = z["0111"] = "string"
z["1100"] = z["1110"] = "strnum"
z["0110"] = "undefined"
return z[x[1] x[2] x[3] x[4]]
}
3番目のパラメータの場合、split
スペースや部分は必要ありません。obj
それ以外の場合は区切り文字として扱われます。私は\1
基準として選ぶスティーブンのアドバイス。この関数は内部CONVFMT
切り替えを実行するため、CONVFMT
関数呼び出し時に値に関係なく正しい結果を返す必要があります。
split("12345.6", q); print 1, o_class(q[1])
CONVFMT = "%.5g"; split("12345.6", q); print 2, o_class(q[1])
split("nan", q); print 3, o_class(q[1])
CONVFMT = "%.6G"; split("nan", q); print 4, o_class(q[1])
結果:
1 strnum
2 strnum
3 strnum
4 strnum
フルテストコレクション:
print 1, o_class(0)
print 2, o_class(1)
print 3, o_class(123456.7)
print 4, o_class(1234567.8)
print 5, o_class(+"inf")
print 6, o_class(+"nan")
print 7, o_class("")
print 8, o_class("0")
print 9, o_class("1")
print 10, o_class("inf")
print 11, o_class("nan")
split("00", q); print 12, o_class(q[1])
split("01", q); print 13, o_class(q[1])
split("nan", q); print 14, o_class(q[1])
split("12345.6", q); print 15, o_class(q[1])
print 16, o_class()
結果:
1 number
2 number
3 number
4 number
5 number
6 number
7 string
8 string
9 string
10 string
11 string
12 strnum
13 strnum
14 strnum
15 strnum
16 undefined
注目すべき弱点:次の「数値文字列」のいずれかを指定すると、関数は「数値」を誤って返します。
- 整数
inf
-inf
整数の場合、説明は次のとおりです。
整数値とまったく同じ数値は、文字列を引数として関数を呼び出すのと同等の方法で文字列に変換する必要があり
sprintf
ます。%d
fmt
ただし、この作業inf
も実行する必要があります。つまり、上記のいずれもこの変数-inf
の影響を受けません。CONVFMT
CONVFMT = "% g"
print "" .1
print "" (+"nan")
print "" 1
print "" (+"inf")
print "" (+"-inf")
結果:
0.1
nan
1
inf
-inf
実際には関係ありません。アヒルテスト。