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

ENDFILE および IGNORECASE を処理するには、GNU awk を使用します。

$ 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

aeiou以外のすべてのアルファベット文字の代わりに特定の文字b、c、dなどを計算するには、( gsub(/[[:alpha:]]/,"&") - gsub(/[aeiou]/,"&") )上記の内容を次のように変更します。gsub(/[bcdfghjklmnpqrtsvwxyz]/,"&"))

句の結果を印刷する他の方法とは異なり、上記のFNR==1両方のスクリプトはファイル名と数でゼロを印刷して空のファイルを正しく処理します。

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を使用している場合はとにかくマルチバイト文字を処理しません)。

関連情報