web-dev-qa-db-ja.com

null文字列を使用して個々の文字を分割する

私はこれをGawkのマニュアルで読みました:

GNU拡張機能

[...]

Null文字列をFSの値として、およびsplit()の3番目の引数として使用して、個々の文字を分割する機能。

しかし、そうではないようです。これは期待どおりに機能します。

$ gawk 'BEGIN {print split("quebec", z, "")}'
6

そして私は他の拡張機能を無効にすることができます:

$ export POSIXLY_CORRECT
$ gawk 'BEGIN {typeof(1)}'
gawk: cmd. line:1: fatal: function `typeof' not defined

しかし、分割動作を無効にすることはできません。

$ export POSIXLY_CORRECT
$ gawk 'BEGIN {print split("quebec", z, "")}'
6

$ gawk --posix 'BEGIN {print split("quebec", z, "")}'
6

Mawkのマニュアルも調べました。

FS = ""の場合、mawkはレコードを個々の文字に分割し、同様に、split(s、A、 "")はsの個々の文字をAに配置します。

[...]

Posixは、FS = ""の動作を未定義のままにし、可能な解釈としてレコードを文字に分割することに言及していますが、現在、この使用法は実装間で移植できません。

では、どの実装では、FSsplitで単一の文字を取得できないのでしょうか?

3
Steven Penny

POSIXは動作を残すため、POSIXスクリプトで使用できないという点でPOSIXではありません詳細不明。つまり、アプリケーション(スクリプト)は移植性が必要な場合は使用できませんが、実装(awk実装)は、必要に応じて実行でき、POSIXのままです。 POSIXでは、awkを文字やバイトに分割したり、エラーを報告したり、コンピューターを再起動したりする必要はありません。指定されていません。

したがって、_$POSIXLY_CORRECT_が環境にある場合、gawkはその動作を変更する理由がありません¹。その場合、他の動作よりも正の動作はありません。

ご存知のように、その拡張機能はgawk(3.0以降、1996年1月)とmawk(バージョン1.2以降、1996年1月)にあります。また、busybox awk(最初(2002)から)にあり、1996年5月以降、Brian Kernighan(kawk)によって維持されているものにもあります(FIXESファイルはgawkなどインスピレーション)。数か月以内に3つすべてに追加されたようで、メンテナの間で話し合われた可能性があります。誰が最初にアイデアを思いついたのか、今はよくわかりません。

Brian KernighanのawkまたはFreeBSDやOpenBSDのようなそれに基づくものでは、空のFSまたは空の3番目の引数がsplit()に渡されると、文字列が個々の文字に分割されることに注意してください(まあ、- bytes、以下を参照)、_awk -F ''_はエラーを返します(_awk -v FS=_はOKですが)。

Solarisでは、nawkと_/usr/xpg4/bin/awk_(および70年代の古い_/bin/awk_)の両方を使用すると、空のFSは分割を完全に無効にするようです。 _nawk -F ''_はエラーを返します。 AIXやHP/UXなどのAT&Tコードに基づく他の商用Unicesでも同じだと思いますが、そこでテストすることはできません。

また、mawk、bwkのawk(一部のbasedでは異なります)、busyboxawkはマルチバイト文字をサポートしていないことに注意してください。したがって、たとえば、UTF-8では次のようになります。

_echo Stéphane | awk -v FS= '{print $4}'
_

私の名で3番目の文字の後半を印刷します。したがって、これらの場合、空のFSは文字ではなく個々のバイトに分割されると言った方が正しいです。


¹POSIXLY_CORRECTまたは_--posix_を使用すると、gawkは、POSIXと競合しない一部の拡張機能を無効にすることに気付きました(typeofgawkを非準拠にします)ので、省略と言えます。今ではそれが最初ではないでしょう。たとえば、POSIXと競合してもnextfileを無効にしません(_awk '{nextfile = 1}'_はnextfile変数に1を割り当てることを意味しますが、POSIXLY_CORRECTでもgawkにエラーを報告します)。

4