Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: webhope 12. 04. 2010, 20:01:12

Název: Regexp pro grep
Přispěvatel: webhope 12. 04. 2010, 20:01:12
Zkouším sestrojit reg. výraz pro grep, ale moc mi to nejde.

Mám např. takovýto kousek kódu:

Kód: [Vybrat]
  urpmi --auto FAAC
  urpmi --auto lame
  urpmi --auto codec
  urpmi.addmedia Main ftp://ftp.free.fr/mirrors/ftp.mandriva.com/MandrivaLinux/official/2010.0/i586/media/main/release
  urpmi.addmedia --update Main_updates ftp://ftp.free.fr/mirrors/ftp.mandriva.com/MandrivaLinux/official/2010.0/i586/media/main/updates
  urpmi.addmedia Contrib ftp://ftp.free.fr/mirrors/ftp.mandriva.com/MandrivaLinux/official/2010.0/i586/media/contrib/release

A chci z toho dostat řádky kde je urpmi --auto

Pak jsou tam další řádky jako:
Kód: [Vybrat]
  deb http://archive.ubuntu.com/ubuntu/ dapper main restricted universe multiverse
  deb http://archive.ubuntu.com/ubuntu/ dapper-updates main restricted universe multiverse
  apt-get install firefox-3.5
  apt-get install mc -y
  apt-get install krusader -y
  dpkg -i skype-ubuntu-intrepid_2.1.0.81-1_i386.deb
  # dpkg -i startupmanager_1.9.12-1_all.deb
  dpkg -i lives_1.1.4-1~getdeb1_i386.deb

A chci z toho dostat řádky kde je apt-get install nebo dpkg.

Zkoušel jsem zatím toto:
hledat="'urpmi'";
cat $0 | grep -E "$hledat";

Mělo by to vrátit více řádků ale vrací jen jeden. Navíc pokud zkusím toto:
Kód: [Vybrat]
hledat="'urpmi[:space:]'";
nebo toto
Kód: [Vybrat]
hledat="'urpmi[[:space:]]'";
nebo toto
Kód: [Vybrat]
hledat="'urpmi\s'";
tak to nenajde nic
Název: Re: Regexp pro grep
Přispěvatel: Lukas 12. 04. 2010, 20:34:58
tohle :

hledat="urpmi --auto"
grep "$hledat" file

mi normalne funguje
Název: Re: Regexp pro grep
Přispěvatel: webhope 12. 04. 2010, 21:05:05
Tak už mi to funguje

Kód: [Vybrat]
hledat="^\s*urpmi[[:space:]]*--auto";
cat $script | grep -E "$hledat"

S těma jednoduchými uvozovkami to nejelo

Edit:
No a kdybych chtěl z toho odstranit řádky, které jsou součástí funkce codec?

Kód: [Vybrat]
function codecs {
if [ "$1" == "mandriva" ]; then
  urpmi --auto FAAC
  urpmi --auto lame
  urpmi --auto codec
  urpmi --auto win32-codecs
  urpmi --auto real-codecs
  urpmi --auto xanim-codecs
  urpmi --auto mozilla-plugin-vlc
fi;

function basic {
if [ "$1" == "mandriva" ]; then
    # urpmi --auto kate
    urpmi --auto krusader
    urpmi --auto opera
    urpmi --auto wine
    urpmi --auto gparted
fi;


Něco aby ta předloha obsahovala, že před ^\s*urpmi nesmí být slovo "codecs". Asi tuším, že bych to měl dát do závorek. Ale jak udělat tu negaci?

Edit 3 (poslední editace):
Úplně nejlepší by bylo definovat oblast textu ve které má hledat. Jde o funkci a o podmínku uvnitř.
Před tím musí být slovo "mandriva" a (NOR) před tím nesmí být slovo "codecs". A za tím (blokem) musí být fi;

Čili je to tak nějak:
funkce nazev1 {
if [ ".." == "mandriva" ]; then .... urpmi ... urpmi ...
fi;
}

funkce nazev2 {
if [ ".." == "mandriva" ]; then .... urpmi ... urpmi ...
fi;
}
Název: Re: Regexp pro grep
Přispěvatel: deadmail 13. 04. 2010, 05:58:37
Vymazat cast medzi function a fi, a potom vypisat vsetky urpmi sa da takto (ale nezarucuje ze za kazdym vypisanym riadkom este bude niekde aj nejake fi):
Kód: [Vybrat]
sed -n '/function codecs/,/fi/d;/^\s*urpmi --auto/p'
Název: Re: Regexp pro grep
Přispěvatel: webhope 13. 04. 2010, 09:29:19
Vymazat cast medzi function a fi, a potom vypisat vsetky urpmi sa da takto (ale nezarucuje ze za kazdym vypisanym riadkom este bude niekde aj nejake fi):
Kód: [Vybrat]
sed -n '/function codecs/,/fi/d;/^\s*urpmi --auto/p'

Zkusil jsem to rozebrat a upravit, ale nefunguje mi to. Jedna věc je totiž funkce (končí špičatou závorkou) a druhá věc je ta podmínka (končí fi;).

Kód: [Vybrat]
      content=$(cat $script | sed -n '/function codecs/,/}/d');
      content=$(echo $content | sed -n '/mandriva/,/fi;}/p');
      content=$(echo $content | sed -n '/^\s*urpmi --auto/p');

Vlastně ani v tom prvním příkazu nevidím žádný výsledek

Ty dva poslední příkazy asi fungují, ale na výstupu to vypadá jak kdyby tam nebyl oddělovač \n. On to asi nebude problém, select to zpracuje i tak.
Název: Re: Regexp pro grep
Přispěvatel: motyq 13. 04. 2010, 09:44:10
mozna by stalo za to napsat co je cilem celeho grepovani.. jak na to koukam tak chcete udelat neco co by slo poresit nejak jednoduseji a ne neco grepovat...
Název: Re: Regexp pro grep
Přispěvatel: webhope 13. 04. 2010, 10:02:07
Jde o to, odfiltrovat funkci codec (pryč s ní). A do výsledku zahrnout blok podmínky "mandriva". Nakonec (a to je cíl) vrátit řádky kde je urpmi. Jinými slovy, cílem je vrátit řádky kde je urpmi, ale netýká se to funkce "codecs" a týká se to pouze mandrivy.

Deadmail už sem napsal jednoduché řešení, jenom se ho teď snažím upravit, tak aby fungovalo tak jak jsem chtěl.
Název: Re: Regexp pro grep
Přispěvatel: David Strejc 13. 04. 2010, 11:08:47
Jsem dementni koder a neumim nic, nez sedlacky grep.

Sorry.

cat $zadek | grep auto | grep mandriva

Jsem v haji.

Potrebuju heroin ;o)
Název: Re: Regexp pro grep
Přispěvatel: David Strejc 13. 04. 2010, 11:10:05
Jsem dementni koder a neumim nic, nez sedlacky grep.

Sorry.

cat $zadek | grep auto | grep mandriva

Jsem v haji.

Potrebuju heroin ;o)

A jako dement tam asi pridam -i - protoze jsem demo. Kapitan demo. Chci si te pridat na fejsbuk.

LIDI VZBUDTE SE!!!!!!!!!!!!!!!!!!!!!!!!

easy.cz
Název: Re: Regexp pro grep
Přispěvatel: webhope 14. 04. 2010, 09:46:43
Tohle mi taky nefunguje. Jenom aby mi to vrátilo celý text souboru kromě té funkce která se odstraní.

Kód: [Vybrat]
script=$0;
content=$(cat $script | sed -n '/function codecs/,/fi;/d');

Když vynechám -n tak se objeví výstup, ale vypadá to jak kdyby to vůbec nebylo profiltrováno:

Kód: [Vybrat]
content=$(cat $script | sed  '/function codecs/,/fi;/d');
content=$(echo $content | sed -n '/mandriva/,/fi;}/p');
content=$(echo $content | sed  '/^\s*urpmi[:space:]--auto/p');

Tak mi bylo sděleno, že toto nemůže fungovat protože sed pracuje jen po jednotlivých řádcích.

Řešení pomocí awk včetně selectu:

Kód: [Vybrat]
awk 'BEGIN{RS="\n}";FS="if"}
!/function codecs/{
   for(i=1;i<=NF;i++){
      if($i~/'$system'/){
        m=split($i,u,"\n")
        for(j=2;j<=m;j++) if(u[j]~/urpmi --auto/){print u[j]}
      }
   }
}' ); 

content=$content$'\E[1;33m\nKonec\E[1;0m';
      # VYBRAT ŘÁDKY
      clear; echo -e $'\E[1;33m''Vyber řádku:'$'\E[1;0m'; OLDIFS=$IFS; IFS=$'\n';
      select line in $content; do
line=$(echo $line | # odfiltrovat funkci 'codecs' a vybrat řádky 'urpmi --auto', které jsou uvnitř podmínky '"mandriva"'
awk ...  # zbyva doresit
     break; done;