2014-09-14 18 views
24

Próbuję uzyskać Perl i GNU/Linux sortowania (1) program uzgodnić, jak sortować ciągi Unicode. Używam sortowania z LANG=en_US.UTF-8. W programie Perl Próbowałem następujące metody:W jaki sposób można sortować według Perla i Uniksa ciągi Unicode w tej samej sekwencji?

Każdy z nich nie powiodło się z następujących błędów (od strony Perl):

  • Inpu t nie jest posortowana: [----] przyszedł po [($ 1]
  • Wejście nie jest posortowana: [...] przyszedł po [&]
  • Wejście nie jest posortowana: [($ 1] przyszedł po [1]

Jedyną metodą, która pracowała dla mnie zaangażowanych ustawienie LC_ALL=C dla rodzaju, a przy użyciu 8-bitowych znaków w Perl. Jednak w ten sposób łańcuchy Unicode nie są poprawnie uporządkowane.

+2

Czy nazywasz "sortowanie" poprawnie? Unicode :: Collate nie zmienia domyślnego zachowania 'sort'; musisz użyć niestandardowej funkcji porównania. – cjm

+0

W rzeczywistości implementuję scalanie-sort w Perlu, więc nie nazywam funkcji sortowania Perla.Ale tak, używam kodu takiego jak 'print STDERR" Wejście nie jest posortowane: [klawisz $] pochodzi po [$ prev] \ n "jeśli (zdefiniowane ($ prev) && $ Collator-> cmp (klawisz $, $ prev) <0); ' –

+2

Rzeczywisty kod Perla (dla znaków 8-bitowych) znajduje się na stronie https://github.com/dspinellis/sgsh/blob/master/sgsh-merge-sum.pl. Jest przeznaczony do łączenia wyjścia wielu 'sort | Wywołania uniq -c'. –

Odpowiedz

5

Używanie Unicode :: Sort lub Unicode :: Sort :: Locale nie ma sensu. Nie próbujesz sortować według definicji Unicode, próbujesz sortować według lokalizacji. Po to jest use locale;.

Nie wiem, dlaczego nie dostałeś pożądanej kolejności od cmp pod use locale;.

Można przetwarzać zdekompresowane pliki.

for q in file1.uniqc file2.uniqc ; do 
    perl -ne's/^\s*(\d+) //; for $c (1..$1) { print }' "$q" 
done | sort | uniq -c 

Oczywiście będzie to wymagać więcej tymczasowego przechowywania, ale otrzymasz dokładnie taką kolejność, jaką chcesz.


znalazłem sprawę use locale; nie powodować Perl sort/cmp dać taki sam wynik jak narzędzia sort. Dziwne.

$ export LC_COLLATE=en_US.UTF-8 

$ perl -Mlocale -e'print for sort { $a cmp $b } <>' data 
(
($1 
1 

$ perl -MPOSIX=strcoll -e'print for sort { strcoll($a, $b) } <>' data 
(
($1 
1 

$ sort data 
(
1 
($1 

Prawdę powiedziawszy, to narzędzie sort jest dziwne.


W komentarzach @ninjalj wskazuje, że dziwność jest prawdopodobnie spowodowana przez znaki o niezdefiniowanych wagach. Podczas porównywania takich znaków kolejność jest nieokreślona, ​​więc różne silniki mogą dawać różne wyniki. Najlepszym sposobem odtworzenia dokładnej kolejności byłoby użycie narzędzia sort przez IPC::Run3, ale wygląda na to, że nie zawsze gwarantuje to tę samą kolejność.

+0

Porównuję wydajność w zestawie danych 20 GB, więc nie mogę sobie pozwolić na nieoptymalne rozwiązanie. Przypadek, który opisujesz, jest dokładnie typem problemu, z którym się borykam. Zwróć uwagę, że nie obchodzi mnie to, jakie ustawienia narodowe będą używane, o ile działa poprawnie z ciągami Unicode (na przykład DUCET) i działa tak samo z sort (1) i Perl. –

+0

Re "Porównuję wydajność w zestawie danych o pojemności 20 GB", więc jakie były wyniki? – ikegami

+0

RE "działa tak samo z sort (1) i Perl", Czy to prawda? Czy rzeczywiście potrzebujesz narzędzia "sort"? – ikegami