Perl을 사용하여 로케일을 기준으로 정렬

Perl을 사용하여 로케일을 기준으로 정렬

다음 데이터는 로캘 정렬 순서에 따라 정렬되어야 합니다.

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

사용하는데 문제 없어요sort

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

로케일을 존중하고

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

로캘이 없습니다.

이제 이 작업을 시도 perl하지만 실패합니다.

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

결과는 정렬의 첫 번째 출력이거나 두 번째 출력입니다.

우분투 12.04 LTS 실행

답변1

문제는 입니다 local $/ = undef. perl전체 파일을 배열로 읽어 들입니다 . @ARGV즉, 파일에는 요소가 하나만 포함되어 있으므로 sort정렬할 수 없습니다(요소가 하나만 포함된 배열을 정렬하기 때문입니다). 출력이 시작 데이터와 동일해야 합니다(다음도 사용합니다 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

제거되면 local $/ = undefPerl은 sort쉘과 동일한 출력을 생성합니다 sort with LC_ALL=C.

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

노트

그렇지 않은 경우 use locale현재 perl로케일이 무시됩니다. Perl 비교 연산자가 ("lt", "le", "cmp", "ge", and "gt")사용되며 LC_COLLATE( LC_ALL존재하지 않는 경우) 기본적으로 사용되므로 sort영향을 받습니다 .cmp

현재 LC_COLLATE값을 얻을 수 있습니다.

$ perl -MPOSIX=setlocale -le 'print setlocale(LC_COLLATE)'
en_US.UTF-8

답변2

파일을 배열로 읽는 올바른 방법은 다음과 같습니다.

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

설정레코드 구분 기호 입력undef는 전체 파일을 스칼라에 넣습니다. 그러면 단일 값의 배열을 정렬하는 것은 별 의미가 없습니다.

어레이 모드에서는 이미 전체 파일을 한 번에 읽을 수 있습니다. 그러면 정렬이 의미가 있습니다.

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

여기 ENVIRONMENT있어요 LANG=en_US.UTF-8. 이 use locale;문이 없으면 기본 LC_ALL=C정렬 체계를 사용하게 됩니다.

더 알고 싶다면:

관련 정보