Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

share|improve this question
1  
What does perl -e 'use locale; local $/ = undef; print sort <>;' < data tell you? –  devnull Mar 23 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 at 16:23

2 Answers 2

up vote 8 down vote accepted

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
share|improve this answer
    
Now it works like charm, thank you! –  user55518 Mar 23 at 17:16
    
You're welcome! But can you explain why my answer is not accepted :) –  cuonglm Mar 23 at 17:17
    
@Ouki posted the right answer one minute earlier. To be fair you've got +1 because your answer is also correct. –  user55518 Mar 23 at 17:20
1  
I think my answer is one minute earlier. Don't mind! –  cuonglm Mar 23 at 17:22
    
lol, ok, so you'll be happier. :-) –  user55518 Mar 23 at 17:26

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:

share|improve this answer
    
Thanks, my bad. :-) –  user55518 Mar 23 at 17:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.