awk -Fがほとんどの文字には機能しますが、文字 "t"には機能しないのはなぜですか?

awk -Fがほとんどの文字には機能しますが、文字 "t"には機能しないのはなぜですか?
 July 2022      mac os Monterey V12.1 
   awk --version 20200816
   GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)

awk -Fほとんどの文字には機能しますが、文字には機能しないのはなぜですかt?解決策がありますが、なぜawkがletterに失敗するのか知りたいのですがt

# Count 'e's
% echo "tweeter" | awk -F "e" '{print NF-1}'
3

# Count 'r's
% echo "tweeter" | awk -F "r" '{print NF-1}'
1

# (Attempt to) count 't's
% echo "tweeter" | awk -F "t" '{print NF-1}'
0   <=== ????

# Use gsub()
% echo "tweeter" | awk '{print gsub(/t/, "")}'
2

答え1

なぜなら:

通常、スペースの数に関係なくフィールドを区切ります。フィールド区切り文字を単一のスペースに設定するには、値と共に-Fオプションを使用します [ ]フィールド区切り文字が指定されている場合、tawkはそれを \t指定どおりに処理し、<TAB>をフィールド区切り文字として使用します。 リテラルをフィールド区切り文字として使用するには、t値と共に-Fオプションを使用します[t]

それが出身です。FreeBSD awk のマニュアルページ、macOSに付属のユーティリティは、通常、いくつかの古いFreeBSDバージョンなどです。

$ printf 'foo\tbar\n' | awk -F t '{print NF-1}'
1
$ echo total | awk -F '[t]' '{print NF-1}'
2

ある意味、これはタブで区切られた値を持つファイルの便利な略称のように見えますが、そのまま使用されている他の文字では混乱します。のように動作し、-F使用し-v FS=tません。

この機能は POSIX ではありません。POSIX とこれは-F xと同じです-v FS=x。私がテストした他のほとんどのawkは、tリテラル処理(gawk、mawk、およびBusyboxのいくつかのバージョン)をテストしました。

たとえば、Debianのawkバージョンはoriginal-awkパック(おそらくBrian W. Kernighanのイニシャルに由来する「One True AWK」または「BWK awk」)はそれをサポートし、少なくともWikipediaによるとこれはFreeBSDで使用するのと同じソフトウェアです。このバージョンは1988年の本「The AWKプログラミング言語」で説明されているバージョンに基づいているようですが、私はawk系統の専門家ではなく、それ以来大きく進んでいるかもしれません。それ羽ハブからしかし、そこにあるドキュメントには機能が説明されていないようです。これ特別な状況についてはコードをご覧ください。(コメントで「カマキリ」と記載されています)

ただし、BWK-awk互換モードでGNU awkを使用すると、同じ動作が得られます。:

特別な場合には、互換モード(コマンドラインオプションセクションを参照)で-Fの引数が "t"の場合、FSはTAB文字に設定されます。引用符なしでシェルに「-F \ t」と入力すると「\」が削除されるため、awkは実際にはフィールドを「t」ではなくタブで区切ると思います。

答え2

これ完全にシェル/環境の組み合わせに関係なく、最も安全な方法は、タブに正方形のケージと二重バックスラッシュを使用することです。

FS='[t]'         # for just lowercase "t"
FS='[\\411]'     # for the tab "\t"

一重引用符の中にあっても\\、一重引用符の中にあっても環境がとてもスマートになり、そのうちの1つを削除しようとすると、awkまだタブ自体として基本バイトになります。

あなたならどうでしょうか?本物それについて妄想を持ってそうする

FS='[\534\564]'  # for the tab "\t"

関連情報