Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Jakub Neburka 15. 01. 2013, 11:21:11

Název: Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 11:21:11
Ahoj.

Potřeboval bych pomoct s regulárním výrazem pro sed. Nějak nechápu, proč mi to nefunguje :) Mým cílem je vypsat všechny definované proměnné, jejichž název obsahuje jen malá písmena, číslice a podtržítko. Zkouším to takto:

declare -p | sed -ne 's/^declare -- \([a-z0-9_]+\)=/\1/p'

K mému údivu se vypíší i proměnné jako PATH, BASH a podobně, tedy proměnné s velkými písmeny :( Kde je chyba?
Zkoušel jsem třeba i:

declare -p | sed -ne '/declare -- [a-z]/p'

s podobným stejnám výsledkem :(
Název: Re:sed REGEX
Přispěvatel: trom 15. 01. 2013, 12:22:54
Kód: [Vybrat]
declare -p |cut -f3 -d" "|cut -f1 -d "=" |grep '[a-z]\+'
tohle mi funguje
Název: Re:sed REGEX
Přispěvatel: Mirek Prýmek 15. 01. 2013, 12:27:41
Citace
     -n      By default, each line of input is echoed to the standard output after all of the commands have been applied to it.  The -n option
             suppresses this behavior.
man sed(1)

Kód: [Vybrat]
# echo X | sed 's/X/Y/'
Y
# echo X | sed -n 's/X/Y/'
#
Název: Re:sed REGEX
Přispěvatel: Jakub Neburka 15. 01. 2013, 12:31:25
Citace
     -n      By default, each line of input is echoed to the standard output after all of the commands have been applied to it.  The -n option
             suppresses this behavior.
man sed(1)

Kód: [Vybrat]
# echo X | sed 's/X/Y/'
Y
# echo X | sed -n 's/X/Y/'
#

Ale vždyť -n používám správně. Problém je s regexem.. :/
Název: Re:sed REGEX
Přispěvatel: Jakub Neburka 15. 01. 2013, 12:40:59
Tak vypadá to, že můj sed nějak zvláštně ignoruje velikost písmen a přitom:
declare -p | sed -ne '/^declare -- [M-P]/p'
vypíše jiný výsledek než
declare -p | sed -ne '/^declare -- [m-p]/p'
ale ten druhý kombinuje veklá i malá písmena O__O. Asi přestanu používat Gentoo :/
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 12:44:32
Na Ubuntu to funguje :) Achjo..
Název: Re:sed REGEX
Přispěvatel: Mirek Prýmek 15. 01. 2013, 12:54:48
Ale vždyť -n používám správně. Problém je s regexem.. :/
Omlouvam se, prehlidl jsem to p na konci... s/ je zbytecny, staci pouzit /.../p

Tak vypadá to, že můj sed nějak zvláštně ignoruje velikost písmen a přitom:
declare -p | sed -ne '/^declare -- [M-P]/p'
vypíše jiný výsledek než
declare -p | sed -ne '/^declare -- [m-p]/p'
ale ten druhý kombinuje veklá i malá písmena O__O. Asi přestanu používat Gentoo :/
To je divny. Co kdyz zkusis tohle?

Kód: [Vybrat]
#  echo 'a' | sed -n '/[a-z]/p'
a
#  echo 'a' | sed -n '/[A-Z]/p'
#  echo 'A' | sed -n '/[A-Z]/p'
A
#  echo 'a' | sed -n '/[A-Z]/p'
#

Jinak ten puvodni pokus ti mozna nemusi fungovat, protoze v klasickych RE je + normalni znak. Zkus pridat -E:
Kód: [Vybrat]
# echo 'aaa' | sed -n '/a+/p'
# echo 'aaa' | sed -En '/a+/p'
aaa

Citace
     -E      Interpret regular expressions as extended (modern) regular
             expressions rather than basic regular expressions (BRE's).  The
             re_format(7) manual page fully describes both formats.
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 12:56:42
Tak to vypadá, že příkaz mám dobře, ale na 64b sedu mi to dává špatné výsledky, zatímco na 32b systému mi to funguje :(

Mimochodem úplné řešení je:
declare -p | sed -ne 's/declare -- \([a-z][a-z0-9_]*\)=.*$/\1/p'
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 12:57:49
Tak to vypadá, že příkaz mám dobře, ale na 64b sedu mi to dává špatné výsledky, zatímco na 32b systému mi to funguje :(
To me hodne zajima, hod jsem nejaky co nejjednodussi priklad, jak ti to dava spatny vysledek.
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 12:59:09
Prýmek: No to -E by bylo hezký, kdyby sed tenhle opšn měl :) Podle mě a manuálových stránek má -E jen grep :) ale máš pravdu, že plusko v BRE není, musel jsem to mírně upravit. Nicméně můj problém s rozbitám 64b sedem to tak jako tak neřeší :/
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 13:04:23
Tak to vypadá, že příkaz mám dobře, ale na 64b sedu mi to dává špatné výsledky, zatímco na 32b systému mi to funguje :(
To me hodne zajima, hod jsem nejaky co nejjednodussi priklad, jak ti to dava spatny vysledek.

Kód: [Vybrat]
declare -p | sed -ne '/^declare -- [a-z]/p'

mi vypíše:
Kód: [Vybrat]
declare -- BASH="/bin/bash"
declare -- BASH_COMMAND
declare -- BASH_SUBSHELL
declare -- BASH_VERSION="4.2.37(1)-release"
declare -- COLUMNS="99"
declare -- COMP_WORDBREAKS
declare -- HISTFILE="/home/neburka/.bash_history"
declare -- HISTFILESIZE="500"
declare -- HISTSIZE="500"
declare -- HOSTNAME="neburkalenovo"
declare -- HOSTTYPE="x86_64"
declare -- IFS="       
declare -- LINES="44"
declare -- MACHTYPE="x86_64-pc-linux-gnu"
declare -- OPTERR="1"
declare -- OSTYPE="linux-gnu"
declare -- PROMPT_COMMAND="echo -ne \"\\033_\${USER}@\${HOSTNAME%%.*}:\${PWD/#\$HOME/~}\\033\\\\\""
declare -- PS1="\\[\\033[01;32m\\]\\u@\\h\\[\\033[01;34m\\] \\w \\\$\\[\\033[00m\\] "
declare -- PS2="> "
declare -- PS4="+ "
declare -- SECONDS

Ještě mám dva typy: buď mám nějak špatně lokalizaci, nebo tomu vadí, že je to přeložené s nls :/
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 13:08:11
Tak to je vtipny. Takze
Kód: [Vybrat]
echo 'a' | sed -n '/[a-z]/p' nevypise nic?

A verze os a sedu?
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 13:12:23
Tak to je vtipny. Takze
Kód: [Vybrat]
echo 'a' | sed -n '/[a-z]/p' nevypise nic?

A verze os a sedu?

vypíše:
a
ale to je v pořádku
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 13:14:11
Takze blbne jenom tohle?

Kód: [Vybrat]
# echo 'A' | sed -n '/[a-z]/p'
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 13:14:59
3.6.11-gentoo
GNU sed version 4.2.1
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 13:17:05
Takze blbne jenom tohle?

Kód: [Vybrat]
# echo 'A' | sed -n '/[a-z]/p'

jo. Skupiny nefungují správně, třeba:
Kód: [Vybrat]
echo 'a' | sed -n '/[:lower:]/p'nevypíše nic a přitom ta skupina je v BRE definovaná
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 13:21:27
Dobrej ulet.

Nemuze byt problem tady?
Citace
Ranges  are  very collating-sequence-dependent[...]Try the same test with export LC_ALL=C
http://www.mail-archive.com/gentoo-user@lists.gentoo.org/msg02154.html
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 13:23:00
Btw, vysvetleni v nasledujicim mailu:

Citace
For example,  in  the  default  C  locale,
>        [a-d] is equivalent to [abcd].  Many locales sort characters in dictio-
>        nary order, and in these locales [a-d] is typically not       
> equivalent  to
>        [abcd];        it  might  be equivalent to [aBbCcDd], for example.  To
> obtain
>        the traditional interpretation of bracket expressions, you can use  the
>        C locale by setting the LC_ALL environment variable to the value C.
http://www.mail-archive.com/gentoo-user@lists.gentoo.org/msg02155.html
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 15. 01. 2013, 13:27:05
Dobrej ulet.

Nemuze byt problem tady?
Citace
Ranges  are  very collating-sequence-dependent[...]Try the same test with export LC_ALL=C
http://www.mail-archive.com/gentoo-user@lists.gentoo.org/msg02154.html

No je to tak! Ty příklady s áčkama najenou fungují.. tedy až na tu [:lower:] skupinu, ale to vem čert. Zvláštní ale je, že se to chová jinak na 64b systému než na 32b. Mám tu ještě jedno 32b zařízení s Gentoo a stejným locale: en_US.UTF-8 a tam to funguje :/
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 15. 01. 2013, 13:45:29
Zvláštní ale je, že se to chová jinak na 64b systému než na 32b.
To se stava...
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: rubicon 16. 01. 2013, 00:25:28
jo. Skupiny nefungují správně, třeba:
Kód: [Vybrat]
echo 'a' | sed -n '/[:lower:]/p'nevypíše nic a přitom ta skupina je v BRE definovaná

Mno, to bude nejspíš tím, že jsi dal sedu za úkol najít znaky ":", "l", "o"..., které on na vstupu nenašel. Posixové třídy znaků se pokud vím musí zadávat následovně:
Kód: [Vybrat]
echo 'a' | sed -n '/[[:lower:]]/p'Navíc, snad v každém dokumentu o RE, který se mi dostal do rukou, je zmiňován tebou finálně odhalený problém s locales.
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Mirek Prýmek 16. 01. 2013, 07:58:55
Navíc, snad v každém dokumentu o RE, který se mi dostal do rukou, je zmiňován tebou finálně odhalený problém s locales.
A není to jenom problém GNU sedu nebo GNU libc? Na MacOS i FreeBSD mi to funguje správně.
Název: Re:Regulární výraz v sed nefunguje
Přispěvatel: Jakub Neburka 16. 01. 2013, 08:48:36
jo. Skupiny nefungují správně, třeba:
Kód: [Vybrat]
echo 'a' | sed -n '/[:lower:]/p'nevypíše nic a přitom ta skupina je v BRE definovaná

Mno, to bude nejspíš tím, že jsi dal sedu za úkol najít znaky ":", "l", "o"..., které on na vstupu nenašel. Posixové třídy znaků se pokud vím musí zadávat následovně:
Kód: [Vybrat]
echo 'a' | sed -n '/[[:lower:]]/p'Navíc, snad v každém dokumentu o RE, který se mi dostal do rukou, je zmiňován tebou finálně odhalený problém s locales.

Ok, žádný učený z nebe nespadl. Mohl si přispět jako první a zamezit tomuto plýtvání slovy :) Teť už si to taky budu pamatovat. Ale nechápu, proč by to mělo na 64b systému a 32b systému funguvat jinak :/ Můžeš mě odkázat na nějaký článek o kterém píšeš?