このページGNU awk実装の制限については、フィールドサイズとリテラル文字列サイズの制限が挙げられますMAX_INT
。
ただし、長い文字列リテラルを変数として宣言し、関数を使用して長さを見つけようとすると、length
文字列の長さが308文字を超えると関数が中断されるようです。以下の例:
BEGIN {
avar=1234... #309 characters
print length(avar) #prints 3 but prints right length when length < 309
}
ただし、次のコマンドラインは1000文字まで機能します。
echo 1234... | awk '{print length($1)}' #tested and works for 1000 characters
CentOS 7システムを使用しており、awkのバージョンは4.0.2です。
この違いが発生する理由に関する提案はありますか?
ベストアンサー1
やりたいことを繰り返すのは簡単です。
awk 'BEGIN {
avar='"$(printf '%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
これは0 1
、200個のゼロからなる完全なリストがawkによって単一に変換されることを意味します0
。これは次のような意味のようです。値0が200個ある整数を書きます。
別の値を指定してみましょう(8の後に0が200個あります)。
➤ awk 'BEGIN {
avar='"$(printf '8%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
799999999999999975786497770008289327579602620364018901185934007602774787484432604273570707237650014944220099327791059265457085874946227877115080328377919022968188728534319854489454506449337030839107584 201
これはの浮動小数点近似値です8e200
。これは次のことで簡単に確認できます。
➤ awk 'BEGIN {
avar='"$(printf '8%0200d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
printf "%15e\n",avar
} '
799999999999999975786497770008289327579602620364018901185934007602774787484432604273570707237650014944220099327791059265457085874946227877115080328377919022968188728534319854489454506449337030839107584 201
8.000000e+200
したがって、コード割り当て()で指定された数値はavar=
数値として(正しく)処理されます。二重浮動小数点数は、最大308までの指数のみを格納できます(非正規数字を除く)。したがって、308ビットを超える値は浮動小数点数に変換できません。
➤ ➤ awk 'BEGIN {
avar='"$(printf '8%0308d' 0)"' #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
printf "%15e\n",avar
} '
inf 3
inf
ただし、文字列なのでavar="..."
二重引用符( )で囲んでも問題はありません。
➤ awk 'BEGIN {
avar="'"$(printf '8%0600d' 0)"'" #309 characters
print avar,length(avar) #prints 3 but prints right length when length < 309
} '
8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 601
データがパイプ(またはファイル)から来る場合、データは文字列と見なされ(data + 0
または同様の数値に変換されない限り)、その長さは文字数です。
$ printf '8%02000d0\n' 0 | awk '{print length($1)}'
2002