Linux är på många sätt ett charmigt operativsystem. Till att börja med är det (oftast) gratis, även om det finns skumma element som då och då försöker göra pengar på det eller delar av det. En annan klämmig sida av Linux är de många frivilliga insatser som gjorts och görs av utvecklare för att uppdatera koden och lägga till nya finesser; tycker du någon detalj saknas kan du ofta ladda ner källkoden, skriva till lite kod, och skicka in för testning och eventuell användning i en kommande release[]. Och tycker man att ett projekt håller på att spåra ur kan man oftast »gaffla» det, dvs starta ett nytt projekt baserat på koden vid ett visst tillfälle i utvecklingen, se till exempel historien om Mambo och Joomla.
Men så är det ju det här med att sortera text under Linux. Jag har varit med i svängen under en längre tid, och har hittills inte stött på något datorsystem som varit särskilt lyckat vad det gäller sortering, men Linux tar ändå priset för det mest sofistikerade upplägget, kombinerat med det mest patetiska misslyckandet. Jag har för eget bruk hackat min Opensuse-burk så att den sorterar som jag vill, men innan jag berättar om mitt hack måste jag beskriva vari problemet ligger; hav tålamod några skärmsidor![]
Låt oss anta att vi vill sortera följande illustrativa och informativa textmassa:
aåä
a äå
å aä
å äa
a åä
aäå
aå ä
ä aå
aä å
Om jag nu, med rosor på kind och solsken i blick, skriver sort fil, så sorterar datorn om texten på nedanstående sätt:
å äa
ä aå
a äå
aä å
aäå
å aä
a åä
aå ä
aåä
Ärligt talat är det inte självklart att texten faktiskt är sorterad och inte randomiserad på något sätt; visserligen har jag »amerikansk engelska» som default, men måste den använda en så bisarr sorteringsalgoritm? Om någon vill försöka lista ut hur sorteringen gått till, så gömmer jag lösningen i den kommande fotnoten; men jag kommer strax att avslöja en av »finesserna» i sorteringen, så i så fall bör ni klura ut det innan ni läser vidare.[].
Vad händer då om man använder »lokalen» (min översättning av det engelska »locale») för svenska? Lokalen för sortering styrs av miljövariabeln LC_COLLATE, och för att för att få svensk sortering kan man enklast skriva LC_COLLATE=sv_SE.UTF-8 sort fil, så får man svensk sortering bara för detta enstaka kommando[]. Nu blir resultatet som följer:
aåä
a åä
aå ä
aäå
a äå
aä å
å aä
å äa
ä aå
Det börjar likna något, eller hur? Ordningen mellan a, å och ä är fixad, men det finns fortfarande ett problem — blankslag hanteras som om de inte existerade, vilket gör sorteringen fel i mina ögon. Ärligt talat vet jag inte hur Svenska Akademin, eller vad det nu kan vara för instans som standardiserar svenska sorteringar, ser på saken, men för mitt ändamål, ett KWIC-index över Anders F Rönnbloms texter, kändes metoden att ignorera blankslag helt bakvänd.
En snabb googling avslöjar att jag inte är den ende att förfasa mig över detta, men som så ofta är de som frågar och svarar engelsktalande, och den lösning de flesta nöjer sig med är att använda kollationeringsordningen »C», som återskapar hur datorer sorterade på stenåldern, då bara engelska talades i datorvärlden. Och då ser resultatet ut så här:
a äå
a åä
aä å
aäå
aå ä
aåä
ä aå
å aä
å äa
Om vi undantar det lilla faktum att »å» och »ä» blivit omkastade så är det så här jag skulle vilja att det ser ut.
Det »traditionella sättet»[] att lösa problemet är att på något sätt mappa om texten så att »å» blir »ä» och vice versa, och sedan mappa tillbaka efter sorteringen; seds kommando »y» är som gjort för denna typ av hack. Men den här gången[] beslöt jag mig för att försöka göra detta enligt Linux alla regler.
För att göra en lång historia kort, jag har ännu inte lyckats. Såvitt jag förstår borde det gå att lösa med de metoder som man använder för att mappa om »basfilen» till lokaler som till exempel den svenska, men jag har inte hittat något sätt att göra det. Huvudproblemet är att alla omdefinieringar jag sett inleds med kommandot »reorder-after», men space-tecknet, det som jag vill ändra, är definierat som det första tecknet i kollationeringsordningen. Jag har därför gått in i den bamsiga huvudfilen och ändrat på egenskaperna hos det allra första tecknet i sorteringsordningen, vilket känns ungefär som att göra en månghundraåriga ek en decimeter kortare genom att kapa den alldeles intill roten, ta av en decimeter på stammen, och sedan limma ihop rasket igen. Eller, som Otis Gibbs uttrycker det i sin fantastiska poddradio »Thanks for giving a damn»: I’d like to say up front that I haven’t the slightest idea what I’m doing, but I decided to do it anyway.
Här är mitt recept för att fixa problemet:
1. Leta rätt på filen iso14651_t1_common; under OpenSuse 12.3 ligger den i foldern /usr/share/i18n/locales, men det kan säkert vara annorlunda i andra distributioner. Öppna filen med lämplig editor[], och gå till den rad som ser ut så här:
<U0020> IGNORE;IGNORE;IGNORE;<U0020> # 32 <SP>
Ändra denna till nedanstående:
#<U0020> IGNORE;IGNORE;IGNORE;<U0020> # 32 <SP>
<U0020> <BAS>;<BAS>;<MIN>;IGNORE # 32 <SP>
Den första raden är naturligtvis bara originalet, sparat som en kommentar för att hålla reda på hur det såg ut innan ändringen; det är en god programmerarpraxis att behålla gammal kod ifall den nya visar sig innebära oväntade katastrofer. Den andra raden utför själva ändringen, och betyder, om jag förstått det rätt, att blanktecknet inte totalt ignoreras, som i raden ovan, utan sorteras som tecknet »BAS», vilket egentligen betyder »utan diakritiska tecken» och är definierat bland diverse arabiska diakritiska tecken; min åsikt är att det torde vara svårt att hitta ett tecken som är mer kemiskt rent på dylika än just blankslaget, och därför valde jag att återanvända detta snarare än att skapa ett nytt tecken.
2. Kompilera en ny lokal med kommandot
localedef -i sv_SE -f UTF-8 sv_SE.UTF-8
Sådär! Nu blir äntligen resultatet som förväntat:
a åä
a äå
aå ä
aåä
aä å
aäå
å aä
å äa
ä aå
Implementeras på egen risk; inga garantier lämnas…
Fotnoter: