BASH 매뉴얼 페이지에 정의된 대로 문자 CLASS별로 임의 파일의 모든 문자를 효율적으로 계산해야 합니다.
[[:alnum:]], [[:alpha:]], [[:ascii:]], [[:blank:]], [[:cntrl:]], [[:digit:]], [[ :그림:]], [[:하단:]], [[:인쇄:]], [[:punct:]], [[:Space:]], [[:상단:]], [[:Word :]] 및 [[:xdigit:]]
파일을 처리한 후 각 결과의 개수가 0이더라도 한 줄에 표시합니다.
인터넷 검색에서는 유사한 콘텐츠를 찾는 데 실패했습니다.
임의의 파일( /tmp/f1.txt
)에는 다양한 텍스트/데이터가 포함됩니다.
나는 ELF 바이너리나 유니코드(또는 모든 형태의 멀티바이트) 콘텐츠를 다루고 싶지 않습니다.
CR
줄 수( 및/또는 ) 는 신경 쓰지 않고 LF
위 클래스를 통해 누적된 대상 파일의 각 "문자" 수만 신경 씁니다.
function()
나는 이것이 결국 더 큰 bash 스크립트 사이의 표준이 되도록 의도하고 있습니다 . bash/sed/awk 등이 필요합니다. Perl/python/ruby는 그다지 필요하지 않습니다.
샘플 데이터 파일은 다음과 같습니다.
0바이트, 즉 콘텐츠가 전혀 없습니다.
단일 문자
단어
여러 단어를 공백으로 구분하세요.
여러 줄에 공백 및/또는 캐리지 리턴 및/또는 줄 바꿈이 포함되어 있습니다.
여러 줄 파일의 경우 마지막 줄의 끝을 나타내는
CR
또는 가 없을 수 있습니다 (그러나 모든 문자는 여전히 계산되어야 합니다).LF
답변1
file=myfile
for class in alnum alpha blank cntrl digit graph lower print punct space upper xdigit
do
printf '%7s: %d\n' "$class" "$(tr -Cd "[:${class}:]" < "$file" | wc -m)"
done
ascii
word
표준 문자 클래스가 아니며 구체적 입니다 bash
. 밑줄이 그어져 word
있고 문자 0~127이므로 다음과 같이 할 수 있습니다.alnum
ascii
printf '%7s: %d\n' word "$(tr -Cd "_[:alnum:]" < "$file" | wc -m)"
printf '%7s: %d\n' ascii "$(LC_ALL=C tr -cd '\0-\177' < "$file" | wc -c)"
(coreutils-8.22부터 GNU 구현은 tr
멀티바이트 문자와 함께 작동할 수 없습니다.)
최소한 GNU libc를 사용하는 시스템에서는 다음을 실행할 수도 있습니다.
$ locale ctype-class-names
upper;lower;alpha;digit;xdigit;space;print;graph;blank;cntrl;punct;alnum;combining;combining_level3
해당 로캘에 정의된 문자 클래스 목록을 찾습니다.
답변2
재미있는 수업인 것 같아요! 그것은 무엇입니까?
이렇게 하면 대부분의 경우 sed가 :ascii: 또는 :word:를 지원하지 않는 것 같습니다.
for f in alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit
do
echo "$f: $(sed s/[^[:$f:]]//g b.txt | tr -d '\n' | wc -c)"
done
우리는 모든 것을 삭제하기 위해 sed를 사용합니다와는 별개로문자에 관심을 갖고 빈 줄을 모두 제거하고 남은 문자 수를 얻습니다.
+/-1 또는 10배 오류를 제외하고 비교적 정확해야 합니다.
답변3
어떤 캐릭터가 어떤 범주에 속하는지는 찾아보지 않겠습니다. 아마도 여러분이 알아낼 수 있거나 다른 답변을 찾아볼 수도 있을 것입니다. 하지만 이렇게 하면 파일 문자를 하나도 잃지 않고 명확하게 표현할 수 있습니다.
_c2o() { od -A n -t o1 -w1 -v | tr -dc '0-9\n' ; }
_c2o <file
163
150
072
040
167
141
162
156
151
156
147
저는 이 기능을 다양한 방법으로 사용하고 있습니다. 각 줄은 8진수 형식으로 표시되는 바이트입니다. 물론 od
매우 구성 가능합니다. 그러나 이 방법을 사용하면 매우 쉽게 목표 값에 대해 행 카운터를 구현할 수 grep
있습니다 sed
. 그것은 케이크 조각입니다. 그리고 그것은 매우 빠릅니다.
좋아요, 그래서 저는 수업을 계속했습니다:
_classes() { set -- ${classes=alnum alpha blank cntrl digit graph lower print punct space upper xdigit}
while ${1+:} false ; do
printf %b $(printf '\\%04o\n' $(seq 0 127)) |
tr -dc "[:${1}:]" | {
printf "$1='"
_c2o
printf "'\n"
} ; shift
done
}
위의 명령을 실행하면 다음과 같은 출력이 표시됩니다.
xdigit='060
061
062
063
064
065
066
067
070
...
'
거기에서 나는 다음과 같은 것을 상상할 것입니다.
eval "$(_classes)"
for class in $classes ; do
eval "$class=\$(_c2o <file | grep -c -F "$class")"
done
이 문제를 더 잘 처리해야 하지만 이것이 효과가 있습니다.