Problem mit "grep -o -i" und $LANG
Hallo, Irgendwie versteher ich hier etwas nicht. Wie arbeitet die Option -o (Ausgabe des passenden Musters) korrekt mit -i (ignore case) zusammen? Irgendwie scheint es bei mir von $LANG abzuhaengen aber das erscheint mir etwas eigenarig: $ export LANG=de_DE.UTF-8 $ LINE="xxxyyyzzz" $ echo $LINE |grep "YYY" -i xxxyyyzzz $ echo $LINE |grep "YYY" -i -o yyy $ echo $LINE |grep "yyy" -i -o yyy bis hierher alles korrekt, aber nun: $ export LANG=en_US $ echo $LINE |grep "YYY" -i -o #nichts, obwohl: $ echo $LINE |grep "YYY" -i xxxyyyzzz # wenn -i eigentlich nicht gebraucht wuerde klappts: $ echo $LINE |grep "yyy" -i -o yyy Ich bin ratlos, kann mir das jemand erklaeren? Achja, das ganze habe ich auf einer SuSE 9.1 gemacht Auf einer UNW,Ultra-5_10 schien -o gar nicht zu klappen wenn das Pattern andere Gross/Kleinschreibung aufweisst als in $LINE - egal wie $LANG gesetzt war. cu Ruediger
Hallo, Am Mon, 28 Feb 2005, Ruediger Meier schrieb: [..]
bis hierher alles korrekt, aber nun: $ export LANG=en_US $ echo $LINE |grep "YYY" -i -o #nichts, obwohl: $ echo $LINE |grep "YYY" -i xxxyyyzzz # wenn -i eigentlich nicht gebraucht wuerde klappts: $ echo $LINE |grep "yyy" -i -o yyy
$ ( LINE="xxxyyyzzz"; echo "$LINE" | grep -i -o "YYY" ; ) grep: invalid option -- o Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more information. $ grep --version | head -n 1 grep (GNU grep) 2.2 Abgesehen davon: mit nem aktuellerem grep 2.5.1 geht's. Das liegt an deiner locale: Aus man grep: A locale LC_foo is specified by examining the three envi ronment variables LC_ALL, LC_foo, LANG, in that order. The first of these variables that is set specifies the locale. Was spuckt bei dir 'locale' aus? Entscheidend ist scheinbar 'LC_COLLATE'... -dnh PS: die Syntax von 'grep' ist: grep [OPTION]... PATTERN [FILE] ... und nicht 'grep PATTERN [OPTION]... [FILE] ...' -- "Wir leben in einem freien Land. Von mir aus kannst du dir auch eine Frikadelle ans Knie nageln und so lange drehen bis du UKW empfängst. Iss mir wurscht." -- Jan Torben in de.comp.os.unix.linux misc
On Monday 28 February 2005 19:49, David Haller wrote:
$ ( LINE="xxxyyyzzz"; echo "$LINE" | grep -i -o "YYY" ; ) grep: invalid option -- o Usage: grep [OPTION]... PATTERN [FILE]...
Abgesehen davon: mit nem aktuellerem grep 2.5.1 geht's. Das liegt an deiner locale: das hab ich auch. ich hab die Optionen auch erst hinten daran gepackt nachdem ich bemerkt habe dass hier geht. Im script hab ich es richtig herum.
Was spuckt bei dir 'locale' aus? Entscheidend ist scheinbar 'LC_COLLATE'...
$ locale LANG=en_US LC_CTYPE="en_US" LC_NUMERIC="en_US" LC_TIME="en_US" LC_COLLATE="en_US" LC_MONETARY="en_US" LC_MESSAGES="en_US" LC_PAPER="en_US" LC_NAME="en_US" LC_ADDRESS="en_US" LC_TELEPHONE="en_US" LC_MEASUREMENT="en_US" LC_IDENTIFICATION="en_US" LC_ALL= Mit diesen locales funktioniert "grep -i -o" nicht. Mit LC_CTYPE="de_DE.UTF-8" gehts dann. (LC_COLLATE scheint keine Rolle zu spielen) LC_CTYPE Character classification and case conversion Es sollte doch aber irgendwie fuer "en_US" auch funktionieren (das ist doch bestimmt der haeufigste verwendete Fall). Is mein grep vielleicht kaputt oder irgendwas anderes? cu Ruediger
Hallo, Am Mon, 28 Feb 2005, Ruediger Meier schrieb:
On Monday 28 February 2005 19:49, David Haller wrote:
$ ( LINE="xxxyyyzzz"; echo "$LINE" | grep -i -o "YYY" ; ) grep: invalid option -- o Usage: grep [OPTION]... PATTERN [FILE]...
Abgesehen davon: mit nem aktuellerem grep 2.5.1 geht's. Das liegt an deiner locale: das hab ich auch. ich hab die Optionen auch erst hinten daran gepackt nachdem ich bemerkt habe dass hier geht. Im script hab ich es richtig herum.
Was spuckt bei dir 'locale' aus? Entscheidend ist scheinbar 'LC_COLLATE'...
$ locale LANG=en_US LC_CTYPE="en_US" LC_NUMERIC="en_US" LC_TIME="en_US" LC_COLLATE="en_US" LC_MONETARY="en_US" LC_MESSAGES="en_US" LC_PAPER="en_US" LC_NAME="en_US" LC_ADDRESS="en_US" LC_TELEPHONE="en_US" LC_MEASUREMENT="en_US" LC_IDENTIFICATION="en_US" LC_ALL=
Mit diesen locales funktioniert "grep -i -o" nicht. Mit LC_CTYPE="de_DE.UTF-8" gehts dann.
(LC_COLLATE scheint keine Rolle zu spielen)
Hm. Bei mir schien es LC_COLLATE (SuSE 9.1) zu sein (Zeilenumbrueche bei leerem 'grep' von mir nachgetragen, da sonst unleserlich): slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_CTYPE="${lang}.${chars}"; \ echo -n "$LANG, $LC_CTYPE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: en_US.UTF-8, en_US.: slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; \ echo -n "$LANG, $LC_COLLATE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: yyy en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: yyy en_US.UTF-8, en_US.: slarty:~ Man beachte, dass LANG jeweils gleich ist -> vgl. man grep bzgl. Auswertungsreihenfolge der Variablen.
LC_CTYPE Character classification and case conversion
Jup, das klingt eigentlich logischer.
Es sollte doch aber irgendwie fuer "en_US" auch funktionieren (das ist doch bestimmt der haeufigste verwendete Fall). Is mein grep vielleicht kaputt oder irgendwas anderes?
S.o. In welcher manpage steht nochmal, welche Teile von $LANG von welchen LC_ beachtet werden bzw. dort relevant sind? Es scheint jedenfalls, dass du ein charset angeben musst. HTH, -dnh --
(void *)'\0' Didn't you see the sign? It said VOID WHERE PROHIBITED Don't tell me you can't C. -- the Internet Oracle [#1307-01]
Hallo, On Tuesday 01 March 2005 01:49, David Haller wrote:
Hm. Bei mir schien es LC_COLLATE (SuSE 9.1) zu sein (Zeilenumbrueche bei leerem 'grep' von mir nachgetragen, da sonst unleserlich):
slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_CTYPE="${lang}.${chars}"; \ echo -n "$LANG, $LC_CTYPE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: en_US.UTF-8, en_US.:
Aber das kann doch nicht gewollt sein! LC_CTYPE="ISO-8859-1" funktioniert NIE - auch komplett mit LC_ALL="ISO-8859-1" und LANG="ISO-8859-1" geht es nicht. Ich weiss nicht genau wieso, aber auf meinem System war/ist bis jetzt LANG="en_US" gesetzt (ohne charset). Was wird dann eigentlich als default charset genommen, sicher ISO. Muss ich LANG bzw. wenigstens LC_CTYPE auf UTF-8 umstellen nur damit grep funtioniert?
slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; \ echo -n "$LANG, $LC_COLLATE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: yyy en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: yyy en_US.UTF-8, en_US.: slarty:~
Hm, aber wenn LANG oder LC_CTYPE charset ISO haben sind diese greps auch immer leer.
Es scheint jedenfalls, dass du ein charset angeben musst.
Ja, aber immer UTF-8!? cu, Ruediger
Hallo, Am Tue, 01 Mar 2005, Ruediger Meier schrieb:
On Tuesday 01 March 2005 01:49, David Haller wrote: [..]
slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; \ ^^^^^^^^^^^^^^^^ echo -n "$LANG, $LC_COLLATE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: yyy ^^^^^^^^^^^^^^^^^^^^^ en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: yyy ^^^^^^^^^^^^^^^^^^^^^ en_US.UTF-8, en_US.: slarty:~
Hm, aber wenn LANG oder LC_CTYPE charset ISO haben sind diese greps auch immer leer.
Nein. s.o.
Es scheint jedenfalls, dass du ein charset angeben musst.
Ja, aber immer UTF-8!?
Nein. s.o. -dnh -- [..] dass man die Tastatur immer wieder mal saeubern sollte damit nicht irgendwelche froehlich vor sich hinrottenden Essensreste zu boesen Killeramoeben, mutieren die zwischen den Tasten hervorquellen und Plaene schmieden um die Weltherrschaft an sich zu reissen. -- J. Grassler
Hallo, On Tuesday 01 March 2005 15:28, David Haller wrote:
Am Tue, 01 Mar 2005, Ruediger Meier schrieb:
On Tuesday 01 March 2005 01:49, David Haller wrote:
[..]
slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; \
^^^^^^^^^^^^^^^^ Wie schon gesagt, LC_COLLATE scheint zwar auch eine Rolle zu spielen aber die Hauptrolle hat LC_CTYPE.
echo -n "$LANG, $LC_COLLATE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: yyy
^^^^^^^^^^^^^^^^^^^^^
Und wie ist LC_CTYPE hier gesetzt?
en_US.UTF-8, de_DE.: en_US.UTF-8, en_US.UTF-8: yyy en_US.UTF-8, en_US.ISO-8859-1: yyy
^^^^^^^^^^^^^^^^^^^^^
en_US.UTF-8, en_US.: slarty:~
Hm, aber wenn LANG oder LC_CTYPE charset ISO haben sind diese greps auch immer leer.
Nein. s.o.
also wenn bei mir "locale" fuer $LC_CTYPE kein oder ein ISO charset anzeigt, dann klappt "grep -i -o" nicht. Das deckt sich auch mit Deinen Angaben, denn $LANG ist bei Dir ja IMMER auf UTF-8 und als Du die Varianten fuer $LC_COLLATE durchprobiert hast war $LC_CTYPE sicher nicht explizit gesetzt also nahm er das UTF-8 von $LANG cu Ruediger
Hallo, Am Tue, 01 Mar 2005, Ruediger Meier schrieb:
On Tuesday 01 March 2005 15:28, David Haller wrote:
Am Tue, 01 Mar 2005, Ruediger Meier schrieb:
On Tuesday 01 March 2005 01:49, David Haller wrote: [..]
slarty:~$ ( LINE="xxxyyyzzz"; for lang in de_DE en_US; do for chars \ in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; \
^^^^^^^^^^^^^^^^ Wie schon gesagt, LC_COLLATE scheint zwar auch eine Rolle zu spielen aber die Hauptrolle hat LC_CTYPE.
Stimmt.
echo -n "$LANG, $LC_COLLATE: "; echo "$LINE" | grep -i -o "YYY" ; \ done; done; ) en_US.UTF-8, de_DE.UTF-8: yyy en_US.UTF-8, de_DE.ISO-8859-1: yyy
^^^^^^^^^^^^^^^^^^^^^ Und wie ist LC_CTYPE hier gesetzt?
Erwischt.
also wenn bei mir "locale" fuer $LC_CTYPE kein oder ein ISO charset anzeigt, dann klappt "grep -i -o" nicht.
Das deckt sich auch mit Deinen Angaben, denn $LANG ist bei Dir ja IMMER auf UTF-8 und als Du die Varianten fuer $LC_COLLATE durchprobiert hast war $LC_CTYPE sicher nicht explizit gesetzt also nahm er das UTF-8 von $LANG
Komisch. Da muesste man mal in den Quelltext / das Changelog schauen. Aber das -o bei grep ist ja eh unportabel, und es geht ja auch anders, naemlich portabel mit sed. slarty:~$ cat /tmp/greptest.sh #!/bin/sh LINE="xxxyyyzzz"; unset LANG LC_ALL LC_CTYPE LC_COLLATE; for lang in de_DE en_US; do for chars in UTF-8 ISO-8859-1 ""; do export LC_COLLATE="${lang}.${chars}"; printf "%32s: grep: %s sed: %s\n" "$LANG, $LC_COLLATE, $LC_CTYPE" \ `echo "$LINE" | grep -i -o "YYY" | grep 'yyy' || echo "___"` \ `echo "$LINE" | sed -n 's/.*\(YYY\).*/\1/ip'`; unset LC_COLLATE export LC_CTYPE="${lang}.${chars}"; printf "%32s: grep: %s sed: %s\n" "$LANG, $LC_COLLATE, $LC_CTYPE" \ `echo "$LINE" | grep -i -o "YYY" | grep 'yyy' || echo "___"` \ `echo "$LINE" | sed -n 's/.*\(YYY\).*/\1/ip'`; done; done; slarty:~$ sh /tmp/greptest.sh , de_DE.UTF-8, : grep: ___ sed: yyy , , de_DE.UTF-8: grep: yyy sed: yyy , de_DE.ISO-8859-1, de_DE.UTF-8: grep: yyy sed: yyy , , de_DE.ISO-8859-1: grep: ___ sed: yyy , de_DE., de_DE.ISO-8859-1: grep: ___ sed: yyy , , de_DE.: grep: ___ sed: yyy , en_US.UTF-8, de_DE.: grep: ___ sed: yyy , , en_US.UTF-8: grep: yyy sed: yyy , en_US.ISO-8859-1, en_US.UTF-8: grep: yyy sed: yyy , , en_US.ISO-8859-1: grep: ___ sed: yyy , en_US., en_US.ISO-8859-1: grep: ___ sed: yyy , , en_US.: grep: ___ sed: yyy -dnh -- Schau Dir Evolution an, das ist mittlerweile genauso dämlich wie Outlook. Ein VBS-Interpreter fehlt noch, aber der kommt bestimmt bald. Das dauert nimmer lang. [Adalbert Michelic in suse-linux]
participants (2)
-
David Haller
-
Ruediger Meier