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

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

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

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

file1 看起来像这样:

bac Dfeg            
k87 eH

tRe
rt up

file2 如下所示:

hi
rt2w
PrOt

但它会打印两个文件的出现次数:

file2 7 19

我怎样才能改变它,以便输出如下:

file1  5 12
file2  2 7
                     

答案1

为了回答这个问题后续问题, 这是我的后续答复使用 GNU awk (现在修改为仅将 b、c、d 等计算为非元音,而不是每个不是 aeiou 的字符,例如,Àé所提到的@StéphaneChazelas在评论中):

$ awk -v IGNORECASE=1 '
    {
        v_cnt += gsub(/[aeiou]/,"")
        c_cnt += gsub(/[bcdfghjklmnpqrtsvwxyz]/,"")
    }
    ENDFILE {
        print FILENAME, v_cnt+0, c_cnt+0
        v_cnt = c_cnt = 0
    }
' file1 file2
file1 5 12
file2 2 7

我将把它作为一个简单的练习,说明如何修改我之前的答案中的 POSIX awk 等效项。

如果您还想要某种指示,如果上面的括号表达式中未列出字母字符,则只需进行以下调整:

awk -v IGNORECASE=1 '
    {
        v_cnt += gsub(/[aeiou]/,"")
        c_cnt += gsub(/[bcdfghjklmnpqrtsvwxyz]/,"")
    }
    /[[:alpha:]]/ {
        gsub(/[^[:alpha:]]+/,"")
        printf "Warning %s[%d]: Unexpected chars found: %s\n", FILENAME, FNR, $0 > "/dev/stderr"
    }
    ENDFILE {
        print FILENAME, v_cnt+0, c_cnt+0
        v_cnt = c_cnt = 0
    }
' file1 file2

如何处理当然可以用各种不同的方式和不同的输出量+细节来处理。

答案2

一种方式使用珀尔如下:

perl -lne '$,=" ";
    $A[0] += +lc =~ tr/aeiou//;
    $A[1] += s/(?![aeiou])[[:alpha:]]//gi;
    print $ARGV, splice @A if eof;
' file1 file2

输出:

file1 5 12
file2 2 7

评论;

  • 数组@A 的第一个元素累加元音的运行总数。
  • 第二个元素累积辅音的运行总数,这些辅音是字母表减去元音的集合。
  • 在当前文件的末尾,数据被转储。注意,拼接的副作用会使数组无效。

相关内容