일부 텍스트 처리 유틸리티를 통해 각 줄의 특정 문자 수를 계산하는 방법을 알고 싶습니다.
예를 들어 "
다음 텍스트의 각 줄을 계산합니다.
"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