Bash 대조 강도(대문자 대 소문자)

Bash 대조 강도(대문자 대 소문자)

입력을 읽고 문자 발생 횟수를 계산하는 스크립트가 있습니다. 이는 배열을 기반으로 합니다.

parse_stream () {
    while read -n 1 char; do
        if [[ -n $char ]]; then
            ((count++))
            ((chars[\\$char]++))
        fi
    done
}

배열 읽기에 대한 간단한 보고서를 인쇄합니다.

print_results () {
    { for i in "${!chars[@]}"; do
        echo -e "$i" "\t"  ${chars["$i"]}
    done } | sort
}

내가 얻은 결과는 알파벳 순서를 유지하지만 소문자와 대문자가 혼합되어 있습니다.

0    3362
[    1
/    1213
:    1628
_    168
1    7282
*    2337
2    3922
+    24
3    2261
4    2042
.    508
5    1624
>    575
6    1879
-    7128
7    1345
8    1895
9    853
A    1
a    2610
b    578
c    1430
C    2
D    1
d    1179
E    2
e    3166
F    1
f    853
G    1
g    962
H    1
h    633
I    11
i    2955
j    254
k    1157
l    2619
M    13
m    1915
n    1590
O    1
o    10983
p    2127
P    3
Q    11
q    118
r    14003
S    1
s    2559
T    2
t    8165
u    1067
v    595
w    4556
X    4
x    7802
y    660
z    193
ź    48

일단 처음에는 대문자이고 다음에는 소문자입니다. 이 문제를 해결할 방법이 있나요?

숫자도 지저분하지만... sort(때때로...왜?...)로 정렬할 수 있습니다. 그것이 중요하다면 우분투가 여기에 있습니다.

전체 스크립트를 볼 수 있습니다여기.

고쳐 쓰다

제가 LANG=pl_PL.UTF-8 sort스크립트에 적용한 함수입니다. 이제 이런 왜곡된 문자는 없지만 여전히 소문자와 대문자에는 왜곡된 문자가 있습니다.

0    3359
1    7281
2    3931
3    2258
4    2046
5    1624
6    1882
7    1346
8    1892
9    846
A    1         #upper
a    2607      #then lower
b    578
c    1430      #lower
C    2         #then upper
D    1

...etc...

내 일반적인 설정은 다르지만 하위 쉘에 의해 상속됩니다.

tomasz@tomasz-Latitude-E4200:~$ echo $LANG
en_US.UTF-8
tomasz@tomasz-Latitude-E4200:~$ (echo $LANG)
en_US.UTF-8

이로 인해 "정상" 또는 이전 동작이 sort어려워집니다.

어쨌든 추가 정렬에서 LANG 정의를 명시적으로 사용하면 대소문자가 여전히 왜곡됩니다.

ll /usr/bin | charstat | LANG=pl_PL.UTF-8 sort

그러면 다음 시퀀스가 ​​생성됩니다.

A    1
a    2607
b    578
c    1430
C    2

고쳐 쓰다

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=pl_PL.UTF-8
LC_TIME=pl_PL.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=pl_PL.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=pl_PL.UTF-8
LC_NAME=pl_PL.UTF-8
LC_ADDRESS=pl_PL.UTF-8
LC_TELEPHONE=pl_PL.UTF-8
LC_MEASUREMENT=pl_PL.UTF-8
LC_IDENTIFICATION=pl_PL.UTF-8
LC_ALL=

답변1

문제는 아니라 bash, 문제는 입니다 sort.

그것은sort로케일실현되었습니다.

명령 을 실행하면 locale아마도 비슷한 내용이 표시될 것입니다 en_US(미국에 있는 경우, 다른 언어에는 다른 로캘이 있음). 인코딩( )도 있을 수 있습니다 en_US.UTF8.

이제 로캘도 정렬에 영향을 줍니다.

간단한 예를 들어보겠습니다:

$ x="a\nA\nc\nC\nb\nB\n"

$ echo -ne "$x" | LANG=C sort
A
B
C
a
b
c

이것이 바로 우리가 원하는 것 같습니다. 하지만...

$ echo -ne "$x" | LANG=en_US sort
a
A
b
B
c
C

어 오!

sort로캘 설정에 따라 동작을 변경할 수 있는 유일한 프로그램은 아닙니다.

설정 전반에 걸쳐 기존의 일관된 동작을 원하는 경우 LANG직접 설정해야 합니다.

이는 드문 일이 아니며 운영 체제가 이미 자체 스크립트의 일부로 이 작업을 수행했을 수 있습니다.

예를 들어...

RedHat/CentOS에서는 많은 /etc/rc.d/init.d스크립트가 이를 수행합니다 /etc/rc.d/init.d/network.

interfaces=$(ls ifcfg* | \
            LANG=C sed -e "$__sed_discard_ignored_files" \
                       -e '/\(ifcfg-lo$\|:\|ifcfg-.*-range\)/d' \
                       -e '/ifcfg-[A-Za-z0-9#\._-]\+$/ { s/^ifcfg-//g;s/[0-9]/ & /}' | \
            LANG=C sort -k 1,1 -k 2n | \
            LANG=C sed 's/ //')

데비안에서는 처음에 , 및 를 /etc/init.d/exim4설정합니다 .LANG=C/usr/bin

관련 정보