入力を読み、文字の発生回数を計算するスクリプトがあります。これは配列に基づいています。
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