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(時々…なぜ?…)で並べ替えることができます。それが重要であれば、Ubuntuはここにあります。

スクリプト全体を見ることができますここ

修正する

私は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/ //')

Debian では、最初に、 と を/etc/init.d/exim4設定します。LANG=C/usr/bin

関連情報