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
相关产品推荐
相关产品推荐

