Автор Гілка: Загадка  (Прочитано 5774 раз)

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Загадка
« : 2007-02-12 14:06:14 »
Ось код на баші:
for I in `echo q w e r t y u i o p a s d f g h j k l z x c v b n m Q W E R T Y U I O P A S D F G H J K L Z X C V B N M| tr ' ' '\n'| sort` ; do case $I in [A-Z]) echo "OK: $I"; ;; *) echo "BAD: $I"; ;; esac; done

Хто мені скаже, коли які символи будуть OK чи BAD і чому? :-)
[Fedora Linux]

Praporshic

  • Гість
Re: Загадка
« Відповідей #1 : 2007-02-12 14:09:20 »
Ось код на баші:
for I in `echo q w e r t y u i o p a s d f g h j k l z x c v b n m Q W E R T Y U I O P A S D F G H J K L Z X C V B N M| tr ' ' '\n'| sort` ; do case $I in [A-Z]) echo "OK: $I"; ;; *) echo "BAD: $I"; ;; esac; done

Хто мені скаже, коли які символи будуть OK чи BAD і чому? :-)
Якщо я вірно пам'ятаю значення [A-Z], то ОК видадуть Q W E R T Y U I O P A S D F G H J K L Z X C V B N M, а усе інше - BAD.

Praporshic

  • Гість
Re: Загадка
« Відповідей #2 : 2007-02-12 14:14:29 »
Таки не вірно пам'ятаю.
Воно видало BAD на "a". Подивився у REGEXP reference і зрозумів що тут не pcre.

zzandy

  • Гість
Re: Загадка
« Відповідей #3 : 2007-02-12 15:35:59 »
[A-Z] - реагує на будь-яку велику латинську літеру, тому правильно не зреагувало на "а". Чи я щось не помітив?

Доречі, в прикладі `echo q ...` можна замінити на просто q w ..., а у третьому баші на {A--z} або {A..z}.
« Змінено: 2007-02-12 15:47:36 від zzandy »

Praporshic

  • Гість
Re: Загадка
« Відповідей #4 : 2007-02-12 17:54:25 »
Так, не помітили. Воно мені сказало OK на усі інші літери. Як на малі, так і на великі.

Відсутній Михайло Даниленко

  • Адміністратор ЩОДО
  • Літератор
  • *****
  • дописів: 1262
  • Карма: +0/-0
  • [Debian Stretch]
Re: Загадка
« Відповідей #5 : 2007-02-12 18:20:20 »
Якщо перед виконанням зробить
export LC_ALL="C"
То воно буде себе вести цілком логічно. Як я розумію, проблема в тому, що воно сортує символи у відповідності до поточної локалі... Але воно видає OK на маленькі літери і коли локаль uk_UA.UTF-8 і коли uk_UA.KOI8-U, отже сортування іде взагалі по unicode mappings?

Відсутній Михайло Даниленко

  • Адміністратор ЩОДО
  • Літератор
  • *****
  • дописів: 1262
  • Карма: +0/-0
  • [Debian Stretch]
Re: Загадка
« Відповідей #6 : 2007-02-12 19:24:17 »
А взагалі, краще користуватися:
for I in {A..Z} {a..z} ; do
        case "${I}" in
        ([[:upper:]])
                echo "OK: ${I}"
                ;;
        (*)
                echo "BAD: ${I}"
                ;;
        esac
done
Тоді все працює в будь-якій локалі.

Відсутній Михайло Даниленко

  • Адміністратор ЩОДО
  • Літератор
  • *****
  • дописів: 1262
  • Карма: +0/-0
  • [Debian Stretch]
Re: Загадка
« Відповідей #7 : 2007-02-12 19:35:48 »
Ага!
Цитата
The sorting order of characters in range expressions is determined by the current locale and the value of the LC_COLLATE shell variable, if set. For example, in the default C locale, ‘[a-dx-z]’ is equivalent to ‘[abcdxyz]’. Many locales sort characters in dictionary order, and in these locales ‘[a-dx-z]’ is typically not equivalent to ‘[abcdxyz]’; it might be equivalent to ‘[aBbCcDdxXyYz]’, for example.
(http://www.network-theory.co.uk/docs/bashref/PatternMatching.html)
Отже, для української локалі маємо якраз останній випадок.

zzandy

  • Гість
Re: Загадка
« Відповідей #8 : 2007-02-12 20:37:11 »
Дивовижне поряд...

Я тут дойшов до дому і спробував наступне:

for i in {A..z} do
   case $i in
        [a-z]) echo "Lower $i";;
        [A-Z]) echo "Upper $i";;
        *) echo "None $i";;
    esac
done

І воно виводить саме те, що і можна подумати - маленькі літери до маленьких, великі - до великих, а все інше окремо. (Локаль uk_UA.UTF-8, LC_ALL не встановлено)


Відсутній Михайло Даниленко

  • Адміністратор ЩОДО
  • Літератор
  • *****
  • дописів: 1262
  • Карма: +0/-0
  • [Debian Stretch]
Re: Загадка
« Відповідей #9 : 2007-02-12 20:57:47 »
[isbear: ~] locale
LANG=uk_UA.UTF-8
LC_CTYPE="uk_UA.UTF-8"
LC_NUMERIC="uk_UA.UTF-8"
LC_TIME="uk_UA.UTF-8"
LC_COLLATE="uk_UA.UTF-8"
LC_MONETARY="uk_UA.UTF-8"
LC_MESSAGES="uk_UA.UTF-8"
LC_PAPER="uk_UA.UTF-8"
LC_NAME="uk_UA.UTF-8"
LC_ADDRESS="uk_UA.UTF-8"
LC_TELEPHONE="uk_UA.UTF-8"
LC_MEASUREMENT="uk_UA.UTF-8"
LC_IDENTIFICATION="uk_UA.UTF-8"
LC_ALL=
[isbear: ~] for i in {A..Z} {a..z} ; do case "${i}" in ([a-z]) echo "OK: ${i}" ;; ([A-Z]) echo "BAD: ${i}" ;; (*) echo "NA: ${i}" ;; esac done ; unset -v i
OK: A
OK: B
OK: C
OK: D
OK: E
OK: F
OK: G
OK: H
OK: I
OK: J
OK: K
OK: L
OK: M
OK: N
OK: O
OK: P
OK: Q
OK: R
OK: S
OK: T
OK: U
OK: V
OK: W
OK: X
OK: Y
BAD: Z
OK: a
OK: b
OK: c
OK: d
OK: e
OK: f
OK: g
OK: h
OK: i
OK: j
OK: k
OK: l
OK: m
OK: n
OK: o
OK: p
OK: q
OK: r
OK: s
OK: t
OK: u
OK: v
OK: w
OK: x
OK: y
OK: z

zzandy

  • Гість
Re: Загадка
« Відповідей #10 : 2007-02-12 21:06:32 »
Вибачте, я там попер проти істини. В мене теж  при LC_ALL='' тільки Z вважається верхнім регістром, а при LC_ALL="C" вже пращює як треба.

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Загадка
« Відповідей #11 : 2007-02-13 16:12:50 »
Ага!
Цитата
The sorting order of characters in range expressions is determined by the current locale and the value of the LC_COLLATE shell variable, if set. For example, in the default C locale, ‘[a-dx-z]’ is equivalent to ‘[abcdxyz]’. Many locales sort characters in dictionary order, and in these locales ‘[a-dx-z]’ is typically not equivalent to ‘[abcdxyz]’; it might be equivalent to ‘[aBbCcDdxXyYz]’, for example.
(http://www.network-theory.co.uk/docs/bashref/PatternMatching.html)
Отже, для української локалі маємо якраз останній випадок.

Приз, в студію! [smiley=10.gif]

Шкода що в ЩОДО не можна дати якусь відзнаку користувачу. :-(

[Fedora Linux]

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Загадка
« Відповідей #12 : 2007-02-13 16:18:25 »
[A-Z] - реагує на будь-яку велику латинську літеру, тому правильно не зреагувало на "а". Чи я щось не помітив?

Доречі, в прикладі `echo q ...` можна замінити на просто q w ...,

Можна, але я хотів щоб воно було посортовано (і цей варіант вимагав найменше зусиль).

Цитата
а у третьому баші на {A--z} або {A..z}.
Ну взагалі-то має бути {A..Z} {a..z}. Я боявся що воно може дати "парну помилку" і може не у всіх спрацювати.
[Fedora Linux]

Відсутній Володимир Лісівка

  • Адміністратор ЩОДО
  • Видавець
  • *****
  • дописів: 3820
  • Карма: +11/-0
  • Програміст
Re: Загадка
« Відповідей #13 : 2007-02-13 16:22:48 »
Дивовижне поряд...

Я тут дойшов до дому і спробував наступне:

for i in {A..z} ; do ;   case $i in         [a-z]) echo "Lower $i";;   [A-Z]) echo "Upper $i";;   *) echo "None $i";;    esac; done
І воно виводить саме те, що і можна подумати - маленькі літери до маленьких, великі - до великих, а все інше окремо. (Локаль uk_UA.UTF-8, LC_ALL не встановлено)


А в мене чомусь тільки A віднесло до верхнього регістру. ;-)

for i in {A..z} ; do  case "$i" in   [a-z]) echo "Lower $i";;   [A-Z]) echo "Upper $i";;   *) echo "None $i";;    esac; done
Upper A
Lower B
Lower C
Lower D
Lower E
Lower F
Lower G
Lower H
Lower I
Lower J
Lower K
Lower L
Lower M
Lower N
Lower O
Lower P
Lower Q
Lower R
Lower S
Lower T
Lower U
Lower V
Lower W
Lower X
Lower Y
Lower Z
None [
NoneNone ]
None ^
None _
None `
Lower a
Lower b
Lower c
Lower d
Lower e
Lower f
Lower g
Lower h
Lower i
Lower j
Lower k
Lower l
Lower m
Lower n
Lower o
Lower p
Lower q
Lower r
Lower s
Lower t
Lower u
Lower v
Lower w
Lower x
Lower y
Lower z
[Fedora Linux]

Відсутній Forum admin

  • Адміністратор ЩОДО
  • Новачок
  • *****
  • дописів: 35
  • Карма: +0/-0
  • Адміністратор форуму
Re: Загадка
« Відповідей #14 : 2007-03-28 22:23:25 »
Ага!
Цитата
The sorting order of characters in range expressions is determined by the current locale and the value of the LC_COLLATE shell variable, if set. For example, in the default C locale, ‘[a-dx-z]’ is equivalent to ‘[abcdxyz]’. Many locales sort characters in dictionary order, and in these locales ‘[a-dx-z]’ is typically not equivalent to ‘[abcdxyz]’; it might be equivalent to ‘[aBbCcDdxXyYz]’, for example.
(http://www.network-theory.co.uk/docs/bashref/PatternMatching.html)
Отже, для української локалі маємо якраз останній випадок.

Приз, в студію! [smiley=10.gif]

Шкода що в ЩОДО не можна дати якусь відзнаку користувачу. :-(


Виявляється що можна.
Отже урочисто (майже  :) ) нагороджується Михайло Даниленко за бла бла  бла.  [smiley=beer.gif]
І хай буде воля моя.
Адмін.