[linux] Re: wtf... regular expressions in awk...

Kees Theunissen theuniss op rijnh.nl
Di Sep 27 02:39:59 CEST 2005


On Mon, 26 Sep 2005, Kees Theunissen wrote:

>Heb je vannacht iets veranderd in je language settings?
>Wat is de waarde van je LC_COLLATE enviroment variable?
>

Dit is misschien een beetje kort door de bocht.
Voor de sorteervolgorde wordt eerst naar LC_ALL gekeken.
Als die niet bestaat naar LC_COLLATE. Daarna eventueel naar LANG.

>Als je de sorteer volgorde hebt staan op iets als AaBbCcDd....
>dan zal [A-Z] iets anders doen dan alleen hoofdletters selecteren.

Ik ben er wel eerder tegen aan gelopen dat scripts anders reageren
dan je verwacht als je locale op een andere waarde is ingesteld
dan "C". Ook oefeningen uit UNIX cursussen kunnen dan anders uitpakken.

Ik ben een beetje aan het spelen geweest op een Fedora Core 4 machine.
Bij de installatie had ik gezegd dat ik US English als taal wilde in de
hoop dat ik dan niet te veel last zou hebben van rare language settings.
Maar dat valt toch tegen.
De LC_* enviroment variabelen zijn niet geset, wel LANG.

[kees op ithmar ~]$ echo $LANG
en_US.UTF-8

Eerst maar eens een test directory aanmaken met enkele files met
zowel uppercase als lowercase namen

[kees op ithmar ~]$ mkdir test; cd test; touch AA BB CC DD aa bb cc dd

Zowel door "ls" als door "sort" wordt nu gesorteerd in de volgorde
aAbBcC....

[kees op ithmar test]$ ls
aa  AA  bb  BB  cc  CC  dd  DD
[kees op ithmar test]$ ls |sort
aa
AA
bb
BB
cc
CC
dd
DD

De pathname expansion van Bash houdt ook deze volgorde aan. Je ziet dat
"aa" niet in de expansion van [A-C]* zit maar "bb" en "cc" wel.

[kees op ithmar test]$ ls [A-C]*
AA  bb  BB  cc  CC

Hetzelfde verhaal geldt bij een regular expresson in awk.
(GNU Awk 3.1.4)

[kees op ithmar test]$ ls |awk '/^[A-C]/'
AA
bb
BB
cc
CC

Een regular expression in "grep" of "egrep" trekt zich niets aan van
$LANG.

[kees op ithmar test]$ ls |grep '^[A-C]'
AA
BB
CC
[kees op ithmar test]$ ls |egrep '^[A-C]'
AA
BB
CC


Ter vergelijking dezelfde opdrachten als $LANG niet geset is.
De sorteer volgorde van "ls" en "sort" wordt eerst alle uppercase
namen, daarna pas lowercase.

[kees op ithmar test]$ unset LANG
[kees op ithmar test]$ ls
AA  BB  CC  DD  aa  bb  cc  dd
[kees op ithmar test]$ ls |sort
AA
BB
CC
DD
aa
bb
cc
dd

Bij de pathname expansion van "ls [A-C]*" in bash verandert wel de
volgorde van de output, maar "bb" en "cc" blijven in de expansie zitten.
Vraag me niet waarom. Is dit een compile time default of zie ik een
optie over het hoofd?

[kees op ithmar test]$ ls [A-C]*
AA  BB  CC  bb  cc

Op een Slackware 10.1 krijg ik hier alleen maar "AA  BB  CC" te zien.
Vreemd. Verder zie ik geen verschillen tussen de Slackware en de Fedora.

De shelloption "nocaseglob" staat toch echt uit.

[kees op ithmar test]$ shopt nocaseglob
nocaseglob      off

Een regular expression in "awk" doet wat je zou verwachten

[kees op ithmar test]$ ls |awk '/^[A-C]/'
AA
BB
CC

Als ik LANG=C zet dan doet ook "ls [A-C]*" wat je zou verwachten.

[kees op ithmar test]$ LANG=C
[kees op ithmar test]$ ls [A-C]*
AA  BB  CC


Zoals je ziet kunnen de language settings onverwachte gevolgen hebben.
Dat kan wel eens vervelend zijn bij de uitvoering van sripts. Iets om
rekening mee te houden.

Groeten,

Kees

-- 
Kees Theunissen
F.O.M.-Instituut voor Plasmafysica "Rijnhuizen", Nieuwegein
E-mail: theuniss op rijnh.nl,     Tel: 030-6096724,     Fax: 030-6031204



More information about the Linux mailing list