空の文字列を使用した単一文字の分割

空の文字列を使用した単一文字の分割

私はGawkのマニュアルで以下を読んだ。

GNU拡張

[...]

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 = ""の動作を未定義のままにし、可能な説明でレコードを文字に分割することに言及していますが、この使用法は現在の実装間で移植可能ではありません。

FSそれでは、およびを使用して単一の文字を取得するために使用できない実装は何ですかsplit

答え1

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

したがって、gawk環境にいるときにこれに関して動作を変更する理由はなく、$POSIXLY_CORRECTこの場合、他の動作よりもPO​​SIXが正しい動作はありません。

発見したように、この拡張はgawk(1996年1月バージョン3.0ベース)とmawk(1996年1月バージョン1.2ベース)に存在します。これはビジボックスawk(最初から(2002)から)にあり、1996年5月からBrian Kernighanが管理する(kin)にもあります(この記事ではawkFIXESgawk、等。インスピレーションとして)。数ヶ月以内に3つすべてが追加されたように見えます。今は誰が最初にアイデアを出したのか分かりません。

Brian Kernighanawkまたはそれに基づくもの(FreeBSDやOpenBSDなど)の場合、空または空の3FS番目の引数を渡すと文字列split()が個々の文字に分割されることに注意してください(もちろん、バイト、以下を参照)、awk -F ''エラーを返します(awk -v FS=しかしそれは大丈夫です)。

Solarisnawkおよび/usr/xpg4/bin/awk(および/bin/awk70 年代以前のバージョン) の場合、null はFS分割を完全に無効にするようです。nawk -F ''エラーを返します。 AIXやHP / UXなどのAT&Tコードに基づく他の商用Unicesでも同様に機能することを願っています。たとえそこでテストすることはできませんが。

また、mawkbwkに注意してくださいawk(一部の人にとってはこれが異なります)。に基づいて上記)とbusybox awkはマルチバイト文字をサポートしていません。たとえば、UTF-8では次のようになります。

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

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


1今、POSIXLY_CORRECTまたはを使用すると、POSIXと競合しない一部の拡張機能が無効になることに気づきました(--posix実際には互換性はありませんが)。したがって、これが欠けていると言うことができます。今これは初めてではありません。たとえば、POSIXと競合しても(変数に1を割り当てますが、POSIXLY_CORRECTでもエラーを報告するという意味)、無効になりません。gawktypeofgawknextfileawk '{nextfile = 1}'nextfilegawk

関連情報