如何用awk分别打印每个文件的辅音出现次数?

如何用awk分别打印每个文件的辅音出现次数?

我正在尝试数辅音的出现多个文件,但我希望单独计算每个文件的出现次数。我用

awk -v FS="" '{for ( i=1;i<=NF;i++){if($i ~/[bcdfghjklmnpqrtsvwxyzBCDEFGHJKLMNPQRTSVWXYZ]/) count_c++}} END {print FILENAME,count_c}' file1 file2

file1 看起来像这样:

bac Dfeg           
k87 eH

tRe        
rt up

file2 如下所示:

hi
rt2w
Prt

但它会打印两个文件的出现次数(output= file2 19)。我怎样才能改变它,使输出如下:

file1 12
file2 7

答案1

使用 GNU awk 处理 ENDFILE 和 IGNORECASE:

$ awk -v IGNORECASE=1 '
    { cnt += ( gsub(/[[:alpha:]]/,"&") - gsub(/[aeiou]/,"&") )}
    ENDFILE { print FILENAME, cnt+0; cnt=0 }
' file1 file2
file1 12
file2 7

或使用任何 POSIX awk:

$ awk '
    { lc=tolower($0); cnt[FILENAME] += (gsub(/[[:alpha:]]/,"&",lc) - gsub(/[aeiou]/,"&",lc)) }
    END { for (i=1; i<ARGC; i++) print ARGV[i], cnt[ARGV[i]]+0 }
' file1 file2
file1 12
file2 7

如果您只想计算特定字符 b、c、d 等,而不是所有非 aeiou 的字母字符,那么只需将( gsub(/[[:alpha:]]/,"&") - gsub(/[aeiou]/,"&") )上面更改为gsub(/[bcdfghjklmnpqrtsvwxyz]/,"&"))

请注意,与在子句中打印结果的任何方法不同FNR==1,上述两个脚本都将通过打印文件名和 0 作为计数来正确处理空文件。

另请注意cnt+0第一个脚本中的 -如果第一个文件为空+0,则确保打印的值将是数字0而不是空字符串。

如果相同的文件名可以在输入中出现多次,则FNR==1{cnt[FILENAME]=0}如果您希望其输出多次,则添加到脚本的开头;if (!seen[ARGV[i]]++) { ... }如果您只想输出一次,则在 END 部分的打印周围添加。

https://unix.stackexchange.com/a/642372/133219来回答同样计算元音的后续问题。

答案2

FWIW,可能不多,如果没有awk:我会很想这样做:

consonants=bcdfghjklmnpqrtsvwxyz
for f in file*; do
    printf "%s %d\n" "$f" "$(< "$f" tr A-Z a-z | tr -dc "$consonants"  | wc -c)"
done

当然,尽管这完全是以 ASCII 为中心的(如果你有 GNU tr,它无论如何也不处理多字节字符。)

相关内容