6

Following data needs to be sorted respecting the locale sort order:

wird
sin
wär
pêche
war
Über
Uber
péché
peach

There was nor problem by using sort

$ sort < data
peach
pêche
péché
sin
Uber
Über
war
wär
wird

which respects the locale, and

$ LC_ALL=C sort < data
Uber
peach
péché
pêche
sin
war
wird
wär
Über

without locale.

Now I tried to do so with perl, but I'm failed:

$ perl -e 'local $/ = undef; print sort <>;' < data
Über
pêche
war
péché
sin
Uber
peach
wär
wird

The result is either the first output of sort, nor the second.

Running Ubuntu 12.04 LTS

2
  • 1
    What does perl -e 'use locale; local $/ = undef; print sort <>;' < data tell you?
    – devnull
    Mar 23, 2014 at 16:15
  • no changes, like the last output. default locale is en_US.UTF-8 but it should work because sort without any settings works too and the data is in utf8.
    – user55518
    Mar 23, 2014 at 16:23

2 Answers 2

8

The problem is local $/ = undef. It causes perl to read entire file in to @ARGV array, meaning it contains only one element, so sort can not sort it (because you are sorting an array with only one element). I expect the output must be the same with your beginning data (I also use Ubuntu 12.04 LTS, perl version 5.14.2:

$ perl -le 'local $/ = undef;print ++$i for <>' < cat
1

$ perl -le 'print ++$i for <>' < cat
1
2
3
4
5
6
7
8
9

If you remove local $/ = undef, perl sort will proceduce same output with the shell sort with LC_ALL=C:

$ perl -e 'print sort <>' < data
Uber
peach
péché
pêche
sin
war
wird
wär
Über

Note

Without use locale, perl ignores your current locale settings. Perl comparison operators ("lt", "le", "cmp", "ge", and "gt") use LC_COLLATE (when LC_ALL absented), and sort is also effected because it use cmp by default.

You can get current LC_COLLATE value:

$ perl -MPOSIX=setlocale -le 'print setlocale(LC_COLLATE)'
en_US.UTF-8
4
  • @Ouki posted the right answer one minute earlier. To be fair you've got +1 because your answer is also correct.
    – user55518
    Mar 23, 2014 at 17:20
  • 1
    I think my answer is one minute earlier. Don't mind!
    – cuonglm
    Mar 23, 2014 at 17:22
  • lol, ok, so you'll be happier. :-)
    – user55518
    Mar 23, 2014 at 17:26
  • Don't mind! I only want to know you have a reason about technique causes you don't accept my answer. Now I know there is no reason:)
    – cuonglm
    Mar 23, 2014 at 17:28
6

Because the correct way to read a file into an array is:

$ perl -e 'print sort <>;' < data

Setting the input record separator to undef is only putting your whole file into a single scalar. Then sorting a single value array does not mean much.

Array mode is already reading your whole file in one shot. Then sorting would be meaningful:

$ perl -e 'use locale; print sort <>;' < data
peach
péché
pêche
sin
Uber
Über
war
wär
wird

Here, my ENVIRONMENT has LANG=en_US.UTF-8. Without the use locale; statement you would use the default LC_ALL=C sorting scheme.

If you want to know more:

0

You must log in to answer this question.