You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

POSIX awk使用FS统计单词出现空字段 如何实现GNU awk FPAT同等效果

假设我有如下文件:

$ cat file
This, that;
this-that or this.

(行尾不一定总有标点……)

现在我需要统计单词,单词的定义为一个及以上不区分大小写的ASCII字母。在常规POSIX *nix环境下可以使用如下命令实现:

sed -nE 's/[^[:alpha:]]+/ /g; s/ $//p' file | tr ' ' "\n"  | tr '[:upper:]' '[:lower:]' | sort | uniq -c
   1 or
   2 that
   3 this

使用grep可以简化写法,仅匹配你定义的单词即可:

grep -oE '[[:alpha:]]+' file | tr '[:upper:]' '[:lower:]' | sort | uniq -c
# 输出同上

使用GNU awk时,你可以使用FPAT直接匹配所需内容来实现同样的效果(忽略排序差异):

gawk -v FPAT="[[:alpha:]]+" '
{for (i=1;i<=NF;i++) {seen[tolower($i)]++}}
END {for (e in seen) printf "%4s %s\n", seen[e], e}' file
   3 this
   1 or
   2 that

我尝试在POSIX awk中复现该功能,写了如下代码:

awk 'BEGIN{FS="[^[:alpha:]]+"}
{ for (i=1;i<=NF;i++) seen[tolower($i)]++ }
END {for (e in seen) printf "%4s %s\n", seen[e], e}' file
   2 
   3 this
   1 or
   2 that

注意输出顶部出现了计数为2的空白条目,这是因为第一行行尾的;和第二行行尾的.产生了空字段。如果删除行尾标点,该问题就会消失。

你可以在awk中设置RS=""来部分修复该问题(除了最后一行外都正常),但最后一行(如果是唯一行的话)仍然会有空字段。

我也可以用如下方式修复:

awk 'BEGIN{FS="[^[:alpha:]]+"}
{ for (i=1;i<=NF;i++) if ($i) seen[tolower($i)]++ }
END {for (e in seen) printf "%4s %s\n", seen[e], e}' file

但这种写法看起来不够简洁直接。我有没有漏掉什么惯用的修复方案,能让POSIX awk的表现和GNU awk的FPAT方案一致?

内容的提问来源于stack exchange,提问作者dawg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:57:01