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위의 두 스크립트 모두 파일 이름과 개수로 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을 사용하는 경우 어쨌든 멀티바이트 문자를 처리하지 않습니다.)

관련 정보