각 줄의 특정 문자 수를 계산하는 방법은 무엇입니까?

각 줄의 특정 문자 수를 계산하는 방법은 무엇입니까?

일부 텍스트 처리 유틸리티를 통해 각 줄의 특정 문자 수를 계산하는 방법을 알고 싶습니다.

예를 들어 "다음 텍스트의 각 줄을 계산합니다.

"hello!" 
Thank you!

첫 번째 행에는 2개가 있고 두 번째 행에는 0이 있습니다.

(또 다른 예는 각 행을 계산하는 것입니다.

답변1

sed다음을 사용하여 이 작업을 수행할 수 있습니다 awk.

$ sed 's/[^"]//g' dat | awk '{ print length }'
2
0

dat예제 텍스트는 어디에 있습니까? sed는 (각 줄마다) "문자가 아닌 모든 것을 제거하고 awk각 줄의 크기를 인쇄합니다 (즉, 현재 줄을 나타내는 위치 length와 동일 ).length($0)$0

다른 캐릭터의 경우 sed 표현식을 변경하면 됩니다. 예를 들어 (:

's/[^(]//g'

고쳐 쓰다: sed작업에 대한 약간의 과잉 - tr적절한 것 이상입니다. 동등한 솔루션 tr은 다음과 같습니다.

$ tr -d -c '"\n' < dat | awk '{ print length; }'

문자 집합(보완 코드를 나타냄)에 없는 tr모든 문자를 삭제한다는 의미입니다 .-c"\n

답변2

나는 awk만 사용할 것이다

awk -F\" '{print NF-1}' <fileName>

여기서는 -F 플래그를 사용하여 필드 구분 기호를 문자로 설정한 "다음 필드 수 NF- 1을 인쇄하는 것뿐입니다. 대상 문자의 발생 횟수는 구분 필드 수보다 1 적습니다.

흥미로운 문자를 셸에서 해석하려면 해당 문자를 이스케이프 처리해야 합니다. 그렇지 않으면 명령줄에서 해당 문자를 해석하려고 합니다. 따라서 두 경우 모두 필드 구분 기호를 이스케이프 처리해야 합니다( 사용 ") .)\

답변3

tr에이드를 사용하세요 wc:

function countchar()
{
    while IFS= read -r i; do printf "%s" "$i" | tr -dc "$1" | wc -m; done
}

용법:

$ countchar '"' <file.txt  #returns one count per line of file.txt
1
3
0

$ countchar ')'           #will count parenthesis from stdin
$ countchar '0123456789'  #will count numbers from stdin

답변4

awk일치하는 수가 너무 많으면(내 경우임) 실패한 답변이 사용됩니다. 답변을 원하시면록키 아스타리, 다음 오류가 보고됩니다.

awk -F" '{print NF-1}' foo.txt 
awk: program limit exceeded: maximum number of fields size=32767
    FILENAME="foo.txt" FNR=1 NR=1

답변을 원하시면엔조팁(그리고 이에 상응하는직원), 분할 오류가 발생합니다.

awk '{ gsub("[^\"]", ""); print length }' foo.txt
Segmentation fault

해결책sed 통과막스 슐렙치거잘 작동하지만 매우 느립니다(아래 시간).

일부 솔루션은 아직 여기에 제안되지 않았습니다. 먼저 다음을 사용하십시오 grep.

grep -o \" foo.txt | wc -w

그리고 사용 perl:

perl -ne '$x+=s/\"//g; END {print "$x\n"}' foo.txt

다음은 일부 솔루션의 타이밍입니다(가장 느린 것부터 가장 빠른 것 순으로 정렬). 여기서는 몇 마디만 말씀드리겠습니다. 'foo.txt'는 단 한 줄과 84922개의 일치 항목을 포함하는 긴 문자열로 구성된 파일입니다.

## sed solution by [maxschlepzig]
$ time sed 's/[^"]//g' foo.txt | awk '{ print length }'
84922
real    0m1.207s
user    0m1.192s
sys     0m0.008s

## using grep
$ time grep -o \" foo.txt | wc -w
84922
real    0m0.109s
user    0m0.100s
sys     0m0.012s

## using perl
$ time perl -ne '$x+=s/\"//g; END {print "$x\n"}' foo.txt
84922
real    0m0.034s
user    0m0.028s
sys     0m0.004s

## the winner: updated tr solution by [maxschlepzig]
$ time tr -d -c '\"\n' < foo.txt |  awk '{ print length }'
84922
real    0m0.016s
user    0m0.012s
sys     0m0.004s

관련 정보