Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: webhope 19. 03. 2010, 09:19:24

Název: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 19. 03. 2010, 09:19:24
Snažím se vytvořit předlohu regularniho vyrazu ke skriptu na editaci souboru /etc/fstab . Předloha má hledat vybraný řádek. Znám hodnoty, které chci do té předlohy dosadit. Získávám je pomocí awk a slučuju do promenne pattern. Akorad tam potřebuju přidat znak whitespace, tedy neco jako \W+ . Mám tento kod:

Kód: [Vybrat]
uuid_=`echo $line | awk  '{print $1,"\W"}'` # stara hodnota - dostat promennou z awk do bashe
dir_=`echo $line | awk  '{print $2,"\W"}'` # stara hodnota - dostat promennou z awk do bashe
fs_=`echo $line | awk  '{print $3,"\W"}'` # stara hodnota - dostat promennou z awk do bashe
zbytek_=`echo $line | awk  '{print $4,"\W"$5,"\W"$6}'` # stara hodnota - dostat promennou z awk do bashe
pattern="$uuid_$dir_$fs_$zbytek_"; echo $pattern; read

Vraci to chybove hlasky: "awk: warning: escape sequence `\W' treated as plain `W'"
Poradite jak to osetrit? Díky

Edit: Sice bych to mohl dát rovnou do toho pattern, ale u promenne zbytek_ potrebuju vrazit to \W* mezi tri sloupce
Název: Re: Vytvoření předlohy reg. výrazu pomocí awk
Přispěvatel: deadmail 19. 03. 2010, 16:27:37
Vobec nie je jasne co presne tam chcete urobit.

V regularnych vyrazoch pouzivany znak \W ma vyznam pri hladani nejakeho textu, ale nie vo vypise (print v awk).

Ciarka v akcii print v prikaze awk vypise oddelovac.

Kod v prispevku vyzera, ze len meni oddelovac na podciarkovnik (underscore) ...

Zmena (len vypis zmeneneho suboru) adresara v jednom riadku (podla povodnej hodnoty) by sa dala cez awk riesit napr. nejako takto:

Kód: [Vybrat]
line=$(tail -1 /etc/fstab) #povodny riadok (posledny z fstab)
dir="adr" #nova hodnota adresara
awk --assign=riadok="$line" --assign=hodnota="$dir" '{if ($0 == riadok) {$2=hodnota};print}' /etc/fstab
Název: Re: Vytvoření předlohy reg. výrazu pomocí awk
Přispěvatel: webhope 19. 03. 2010, 17:48:01
Teď nevím co ten Váš kód udělá, to zapisuje rovnou do fstab?

Chtěl jsem jen toto - vytvorit predlohu jako "uuid=asdasdasd\W*/media/pokus\W*NTFS-3G\W*defaults,umask=000\W*0\W*"
Potřeboval bych jen lehce upravit ten můj kód, te zkouším změnu, stejně bez výsledku - stejný chyba. Chci do výstupu k $1 přidat zpětné lomítko a W*. Tedy aby se u každé proměnné nastavilo neco jako "text\W*"

Kód: [Vybrat]
id_=`echo $line | awk  '{print "$1 \W"}'` # stara hodnota - dostat promennou z awk do bashe
dir_=`echo $line | awk  '{print "$2 \W"}'` # stara hodnota - dostat promennou z awk do bashe
fs_=`echo $line | awk  '{print "$3 \W"}'` # stara hodnota - dostat promennou z awk do bashe
zbytek_=`echo $line | awk  '{print $4,"\W"$5,"\W"$6}'` # stara hodnota - dostat promennou z awk do bashe
pattern="$id_$dir_$fs_$zbytek_"; echo $pattern; read

edit:
co za jazyk pouziva ten awk, z ceho vychazi? je to perl?
Název: Re: Vytvoření předlohy reg. výrazu pomocí awk
Přispěvatel: deadmail 19. 03. 2010, 20:35:51
ziadnu zmenu v subore fstab nerobi, len vypisuje na obrazovku. Bez obav mozete vyskusat ten kod, nic nemeni.

Ak chcete vypisat lomitko, tak ho musite "escapovat" = napisat dvakrat \\.

Kód: [Vybrat]
echo "Ahoj svet" | awk '{print $1"\\"$2}'
Název: Re: Vytvoření předlohy reg. výrazu pomocí awk
Přispěvatel: webhope 20. 03. 2010, 08:22:51
Tak awk sice funguje:

Kód: [Vybrat]
echo "Tak toto je muj prvni pokus s awk" | awk  '{print $4"\\W"$5"\\W"$6}'

ale ja potrebuju ten vystup z awk ulozit do promenne. Delam to pomocit zpetnych uvozovek a proto to hlasi chybu:

Kód: [Vybrat]
id_=`echo $line | awk  '{print $1"\\"}'`
Čili ty zpetna lomitka se to snazi interpretovat jako wildcard

Edit:
Takže už to mám. Já vlastně na výstup musím dostat dvě zpětné lomítka, ne jedno:

Kód: [Vybrat]
id_=`echo $line | awk  '{print $1"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
dir_=`echo $line | awk  '{print $2"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
fs_=`echo $line | awk  '{print $3"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
zbytek_=`echo $line | awk  '{print $4"\\\\W*"$5"\\\\W*"$6}'` # stara hodnota - dostat promennou z awk do bashe
pattern="$id_$dir_$fs_$zbytek_"; echo $pattern; read

UUID=2090ACC103B52D41\W*/media/win_c\W*ntfs-3g\W*defaults,umask=000\W*0\W*0

Tak teď to jdu vyzkoušet, jestli mi bude fungovat ta předloha pro nahrazování. Zatim nefunguje.

Kód: [Vybrat]
replaced=${line//pattern/"tak toto je prepsana radka"};
Název: Re: Vytvoření předlohy reg. výrazu pomocí awk
Přispěvatel: webhope 20. 03. 2010, 08:43:00
Tak ještě řeším toto:
1) nefunguje mi to nahrazení pomocí regulárního výrazu
2) ta proměnná $replaced je přístupná pouze uvnitř cyklu while ... do ... done; Ale za tím cyklem už přístupná není. Tohle neumím vyřešit...

Kód: [Vybrat]
# EDITACE SOUBORU /etc/fstab
n=0;echo "Vyber radek k editaci:"; read number; clear; echo -e "Vybral si radek:";
number=$number; # pokud to neulozim tak se promenna pri dalsim read vymaze
grep $e /etc/fstab | while read line; do
    let "n += 1";
    if [ "$n" == "$number" ]; then  # POCET OD NULY
      echo "$line" | awk '{print $1," \033[1;32m",$2,"\033[1;36m", $3, "\033[1;0m", $4, $5}';
      #awk -v w="$line" '{print w}'# dostat promennou do awk
      id_=`echo $line | awk  '{print $1"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
      dir_=`echo $line | awk  '{print $2"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
      fs_=`echo $line | awk  '{print $3"\\\\W*"}'` # stara hodnota - dostat promennou z awk do bashe
      zbytek_=`echo $line | awk  '{print $4"\\\\W*"$5"\\\\W*"$6}'` # stara hodnota - dostat promennou z awk do bashe
      pattern="$id_$dir_$fs_$zbytek_"; echo $pattern; read
      if [ "$dir_" == "/" ]; then escape=1; echo "Bod / pro pripojeni systemoveho oddilu neni povoleno nastavit."; fi;
      if [ "$dir_" == "/home" ]; then escape=1; echo "Bod /home neni povoleno nastavit."; fi;
      if [ "$dir_" == "swap" ]; then escape=1; echo "Oddil swap neni povoleno nastavit."; fi;
      replaced=${line//pattern/"tak toto je prepsana radka"};
echo $replaced"\n";
echo $pattern; read
    fi;
done
echo $replaced"\n";
echo $pattern; read
if [ "$escape" != "1" ]; then # pokud vybral / nebo /home, neaplikovat

Možná to dělám moc složitě, ale i tak bych to chtěl vyřešit. Když tak bych pak zkusil udelat to pomocí selectu, tím by odpadl problém s tou proměnnou mimo cyklus.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 20. 03. 2010, 16:06:00
Citace
Možná to dělám moc složitě, ale i tak bych to chtěl vyřešit. Když tak bych pak zkusil udelat to pomocí selectu ...

Riesenie cez select (bez farieb):

Kód: [Vybrat]
#!/bin/bash
set +x
hledat=("NTFS" "Linux" "Oba" "Koniec");
PS3="Vyber si OS: "
select hledam in "${hledat[@]}"; do
 case $hledam in
  ${hledat[0]}) e="ntfs-3g"; break;;
  ${hledat[1]}) e="ext[2-4]"; break;;
  ${hledat[2]}) e="ntfs-3g\|ext[2-4]"; break;;
  ${hledat[3]}) exit 2;;
 esac
done

arr=$(grep "$e" /etc/fstab)
if [ "$arr" == "" ]
then
 echo "No line found!"
 exit 1
fi
echo "Vyber radek k editaci"
OLDIFS=$IFS
IFS=$'\n'
PS3="Vyber si riadok: "
select array in $arr
do
  line="$array"
  break
done
IFS=$OLDIFS

#echo "Vybraty riadok: $line"
dir=`echo $line|awk '{print $2}'`
if [[ "$dir" =~ "^/\|/home\|/swap$" ]]
then
 echo "Nemozno menit adresar $dir"
 exit 3
else
 echo "Upraveny fstab by vyzeral takto:"
 awk --assign=riadok="$line" '{if ($0 == riadok) {$0="prepisany riadok"};print}' /etc/fstab
fi
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 20. 03. 2010, 17:35:06
To je sice pěkné, že si to přepsal celé jinak, ale já bych rád dořešil ten svůj kód, ať se toho mohu nějak poučit. Jde mi o to nahrazení přes regul. výraz a předání proměnné mimo cyklus, který jsem uvedl. Tzn. aby se mi ta proměnná neztratila/nevynulovala.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 21. 03. 2010, 04:34:44
Ak chceme zmenit riadok cislo, tak sa to da urobit rychlo:

Kód: [Vybrat]
read -p "Vyber cislo riadku: " number

grep "ext[2-4]" /etc/fstab | awk --assign=number="$number" '{if (NR == number) print "tak totok je prepsana radka"; else print}' #pomocou awk

grep "ext[2-4]" /etc/fstab | sed "${number}s/.*/tak toto je zmeneny riadok/" #cez sed

Kód: [Vybrat]

Na zistenie kazdej premennej spustat novy awk na ten isty text a potom robit nahradzovanie v bashi je dost prekomplikovane ... no ale co sa tyka while, tak problem je  s pipe-ou (|), spusta sa novy proces a preto premennu dalej v skripte "nevidno". Ak sa v cykle nic nevypisuje, tak sa to da obist vypisanim hodnotu a priradenim celeho prikazu (prem=$(grep| while ...)) do premennej. Druha moznost je spustit while a presmerovat mu vstup bez pipe:

Kód: [Vybrat]
while read line
do
 riadok=$line
done < <(grep "ext[2-4]" /etc/fstab)
echo $riadok #vypise posledny riadok s ext?
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 21. 03. 2010, 07:21:28
Deadmail: Ten poslední kód cos napsal je pecka. Ale co znamená " < <" . Proč tam jsou dvě menšítka a ne jedno?

Já jsem si toho už všiml a tak jsem to opravil. Akordád jsem to už včera sem nevložil. Napsal jsem tuto předlohu:

Kód: [Vybrat]
pattern=`echo $line | awk  '{print $1"[:space:]*"$2"[:space:]*"$3"[:space:]*"$4"[:space:]*"$5"[:space:]*"$6}'` # stara hodnota - dostat A tímto jsem to zkousel nahradit:
Kód: [Vybrat]
echo ${path_name##/*/replacement}

No a to mi nefunguje. Nenahradi to. Chybovou hlasku uz nepise.

Kód: [Vybrat]
pattern=`echo $line | awk  '{print $1""}'` # zkousel jsem i zjednodusenou variantu
pattern=`echo "UUID=2090ACC103B52D41 /media/win_c ntfs-3g defaults,umask=000 0 0" | awk  '{print $1}'` # a zkousel jsem pro vytvoreni predlohy doplnit text primo
replacement="zameneny retezec - pokus - "
replaced=${line//pattern#/replacement};
replacement="asdasdasddd"
echo ${path_name##/*/replacement}
read

Edit:
Můžeš mi prosímtě ještě vysvětlit co znamená to ext[2-4] v grepu. Respektive co znamená to ext. Pres info a man jsem o tom  nenasel nic.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 22. 03. 2010, 07:02:08
"ext[2-4]" je regularny vyraz (Regular Expression) zastupujuci retazce, kde prve tri znaky su e, x a t, stvrty znak je z rozsahu 2-4, teda zastupuje 3 retazce ext2, ext3, ext4 (linuxove filesystemy). Viac napr. aj v seriali o RE tu na root-e (http://www.root.cz/serialy/regularni-vyrazy/).

Presmerovania (redirection):
prikaz <subor ... obsah suboru je vstupom prikazu
prikaz1 $(prikaz2), prikaz1 `prikaz2` ... spusti prikaz2 a jeho vystup zapise ako parametre pre prikaz1
prikaz1 <(prikaz2) ... spusti prikaz2, vystup zapise do docasneho suboru a potom ako parameter pre prikaz1 da nazov tohto docasneho suboru
prikaz1 | prikaz2 ... vstupom prikaz2 je vystup prikaz1 (rura, pipe)
prikaz1 < <(prikaz2) ... vystup prikaz2 sa zapise do docasneho suboru a ten subor sa da ako vstup pre prikaz1 (teda prepojenie ako cez ruru)
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 22. 03. 2010, 07:53:17
Regulární výrazy už znám, ale tohle ačkoliv je to základ, mi nějak nedošlo. Ty další věci, díky, některé už znám a ty další, zkusím si to nějak zapamatovat. Nepřišel si na to přič mi nefunguje to nahrazování? paterrn//var/replace ? To je tak poslední věc co potřebuju vyřešit. Se zbytkem bych si už pohrál sám. Díkes
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 22. 03. 2010, 09:28:48
Co som pozeral, tak stale hladas text "pattern" a nie podla hodnoty premennej (chyba $ pred nazvom).

Vypis riadku so zmenenim tretieho pola sa da urobit napr. takto (funguje ak v riadku nie su rovnake polia  a pole neobsahuje znak "/"):
Kód: [Vybrat]
line="UUID=2090ACC103B52D41 /media/win_c ntfs-3g defaults,umask=000 0 0"
pattern=`echo $line|awk '{print $3}'`
zmena="ext2"
echo ${line/$pattern/$zmena}

Aby to fungovalo aj pre druhy stlpec (obsahuje lomitko), tak treba upravit=escapovat lomitko, napr. prikazom (medzi riadky pattern a echo)
Kód: [Vybrat]
pattern=${pattern//\//\\\/} # nahrad vsetky / znakmi \/
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 22. 03. 2010, 11:37:19
Já myslel, že když tam je ${} tak dovnitř už se dolar nepíše. Tak jsem si to asi s něčím spletl. Ta záměna lomítek mě taky napadla, ale jelikož nefungovalo to nahrazování, tak jsem to nezkoušel. Díky.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 23. 03. 2010, 08:34:39
Tak tady je moje řešení:

Kód: [Vybrat]
n=0;echo "Vyber radek k editaci:"; read number; clear; echo -e "Vybral si radek:";
  number=$number; # pokud to neulozim tak se promenna pri dalsim read vymaze
  pattern=$( grep $e /etc/fstab | while read line; do
let "n += 1";
if [ "$n" == "$number" ]; then  # POCET OD NULY
  dir_=`echo $line | awk  '{print }'` # stara hodnota - dostat promennou z awk do bashe
  if [ "$dir_" == "/" ]; then escape=1; echo "Bod / pro pripojeni systemoveho oddilu neni povoleno nastavit."; fi;
  if [ "$dir_" == "/home" ]; then escape=1; echo "Bod /home neni povoleno nastavit."; fi;
  if [ "$dir_" == "swap" ]; then escape=1; echo "Oddil swap neni povoleno nastavit."; fi;
  #awk -v w="$line" '{print w}'# dostat promennou do awk
  echo "$line" | awk '{print $1," \033[1;32m",$1,"\033[1;36m", $3, "\033[1;0m", $4, $5}';
  echo "TOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE";
  echo $line | awk  '{print $1"[:space:]*"$1"[:space:]*"$3"[:space:]*"$4"[:space:]*"$5"[:space:]*"$6}' # stara hodnota - dostat promennou z awk do bashe
fi;
    done)
    hlaska=${pattern%TOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE*} # smazat od konce (od posledního výskytu)
    pattern=${pattern#*TOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE} # smazat od začátku (od prvního výskytu)
    echo -e $hlaska;
    echo $pattern;
    read

Možná složitější,ale je moje :-)
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 23. 03. 2010, 11:45:48
Jinak ale, ještě bych to potřeboval přejmenovat a uložit do souboru a toto mi nefunguje:
pattern=${pattern//\//\\\/}

Kód: [Vybrat]
sed -i -e "s%$pattern%$new_line%" /etc/fstab
a dostávám hlášku:
sed: -e výraz č. 1, znak 2: neukončený příkaz „s“
zkoušel jsem to i s normálními lomítky / a taky bez -i -e ale bez výsledku. Dělal jsem to podle "info sed" tak nevím proč to nejde.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 24. 03. 2010, 05:36:09
Citace
Kód: [Vybrat]
sed -i -e "s%$pattern%$new_line%" /etc/fstabsed: -e výraz č. 1, znak 2: neukončený příkaz „s“

Problem je s premennou pattern. Podla kodu o prispevok vyssie, tak obsahuje odriadkovanie na zaciatku. Skus
Kód: [Vybrat]
echo "%s$pattern%"
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 24. 03. 2010, 05:37:24
oprava:

Kód: [Vybrat]
echo "s%$pattern%"
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 24. 03. 2010, 05:41:18
Citace
Kód: [Vybrat]
awk  '{print $1"[:space:]*"$1"[:space:]*"$3"[:space:]*"$4"[:space:]*"$5"[:space:]*"$6}'

Nemali by tam byt hviezdicky, ale \+ (aspon jedna medzera)
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 24. 03. 2010, 08:17:50
Dobre. To co tedy v podstate mam je neco take:

Kód: [Vybrat]
pattern="tento radek je zprava pro uzivatele.... bla bla.
tento radek je oddelovac
tento radek je predloha - to co se ma vyfiltrovat
"

Hodnota promenne pattern se vygenerovala pomoci grep a cyklu while.
A jak mam ted teda postupovat? Mam pro predlohu nastavit rezim multiline? Ja znam regularni vyrazy jen z PHP a tam by to bylo myslim \M. Nebo raději pouzit označeni konce a začátku řádku? Tak aby to hledalo po řádcích. To se mi zdá rozumnější. Ale nevím jak to udělat. Nemám dost jasno jaké jsou rozdíly mezi reg.exp. v awk, sed a parameter subsitution?

Ve svem scriptu jsem si chyby s hvezdickou uz vsiml a opravil na+. Nicméně do předloh se musí dávat vždy zpětné lomítko před kvantifikátor?

Z tohoto
Kód: [Vybrat]
hlaska=${s%pattern%\nTOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE*} # smazat od konce (od posledního výskytu)
pattern=${s#pattern#*\nTOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE} # smazat od začátku (od prvního výskytu)
výskytu)
Potrebuju vymazat vse od \nTOTO_JE_JEN_ODDELOVAC_KTERY_ODDELI_HLASKU_OD_PREDLOHY_SAMOTNE az do konce

Současná hláška:
sed: -e výraz č. 1, znak 0: žádný předcházející regulární výraz
sed: -e výraz č. 1, znak 0: žádný předcházející regulární výraz
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 25. 03. 2010, 09:26:16
Kód: [Vybrat]
pattern="tento radek je zprava pro uzivatele.... bla bla.
tento radek je oddelovac
tento radek je predloha - to co se ma vyfiltrovat
"

Tak vysledne riadky by som spracoval cez sed (ten oddelovac tam nemusi byt ak je to na viacerych riadkoch:
Kód: [Vybrat]
pattern="tento radek je zprava pro uzivatele.... bla bla.
tento radek je oddelovac
tento radek je predloha - to co se ma vyfiltrovat
"
sprava=$(echo "$pattern" | sed -n '1p') #vypis prveho riadku
predloha=$(echo "$pattern" | sed -n '3p')

Je to v troch riadkoch, lebo kazde echo vypise koniec riadku - bolo by v jednom riadku, ak by sa spustalo echo -n

Co sa tyka znaku + zavisi od pouzitych reg. vyrazov (BRE, ERE, PERL regex - vid wikipedia (http://"en.wikipedia.org/wiki/Regular_expression"))... + v grepe (BRE) oznacuje znak plus a \+ pocet (aspon jeden krat). V egrep (ERE) je to presne naopak.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 25. 03. 2010, 10:50:54
Díky za odpověď. Jak budu na linuxu, tak to vyzkouším.

Edit
Našel jsem taky jedny pěkné stránky (hezky zformátovaný text):
http://www.zytrax.com/tech/web/regex.htm

Ale nenašel jsem tam bash. Bash je ERE nebo BRE? Ptám se kvůli parameter substitution.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 25. 03. 2010, 18:56:08
Stále mi nejede ta předloha v sedu:

Předloha:
UUID=2090ACC103B52D41[:space:]\+\/media\/win_c[:space:]\+ntfs-3g[:space:]\+defaults,umask=000[:space:]\+0[:space:]\+0   

fstab:
# Entry for /dev/sda1 :                                                       
UUID=2090ACC103B52D41 /media/win_c ntfs-3g defaults,umask=000 0 0

Sed:
Kód: [Vybrat]
sed -e "s%$pattern%$new_line%" /etc/fstab
pattern=${pattern//\//\\\/}
sed -e "s%$pattern%$new_line%" /etc/fstab

Výsledek žádný, soubor nezměněn

Nahrazovací řetězec je:
UUID=E0CC96C0CC969080 /media/pokus ntfs-3g defaults,umask=000 0 0

Ale jsou tam mezery. Není to problém?
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 25. 03. 2010, 20:59:52
Citace
UUID=2090ACC103B52D41[:space:]\+ ...
[:space:] apod. sa mozu pouzivat iba v zozname znakov [], teda ak chcem len medzeru/biely znak, tak [[:space:]].

Prikazom sed sa subor nemeni, len by to malo vypisat zmenene na obrazovku. Pre zmenu treba pouzit prepinac -i.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 26. 03. 2010, 08:00:36
Aha, já myslel, že  -i je insensitive.
Skvělé, povedlo se to :-) Tak dík za pomoc. Myslím, že teď už těm reg.exp. víc rozumím.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 26. 03. 2010, 08:35:58
Citace
Aha, já myslel, že  -i je insensitive.

Ono to zavisi od prikazu:
grep -i ... ignore case
sed -i ... inplace editing
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 26. 03. 2010, 13:06:20
Nevíš proč mi nejde toto:

Kód: [Vybrat]
for file in ${seznam[@]}; do
  i+=1;
  adresare[$i]=$( mount | grep $cesta/$file )
done;

Výstup od mount je:
/dev/sda1 on /mnt/i type fuseblk (rw,allow_other,blksize=4096)

No a hlásí mi to tuto chybu:
adresare[$i]: chybný podskript pole

Když spustím
mount | grep $cesta/$file
samostatně tak to funguje
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 26. 03. 2010, 21:04:23
Citace
i+=1;
Mne to generuje 1, 11, 111, ...

Asi to malo byt:
Kód: [Vybrat]
i=$((i+1))
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: NN 26. 03. 2010, 22:09:49
Spise ted:

i++

NN
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 27. 03. 2010, 00:50:19
Funguje :-) - Podle Deadmail

Podle NN píše
./set_fstab.sh: řádek 32: i++: příkaz nenalezen
/dev/sda1 on /mnt/i type fuseblk (rw,allow_other,blksize=4096)
./set_fstab.sh: řádek 33: adresare_prip[$i]: chybný podskript pole
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 27. 03. 2010, 10:23:54
Citace
Spise ted:

i++

V bash-i (ver. 3.2.39) nefunguje ani i++, ani i=$((i++)) ...
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 31. 03. 2010, 18:51:38
V jednom svém skriptu jsem našel tohle řešení:

Kód: [Vybrat]
let "n += 1";
let "c=($n+1)";
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 06. 04. 2010, 16:54:03
Tak zase řeším to co na začátku. Už mi to fungovalo, ale teď jsem nějak rozdrfal nastavení IFS a awk nefunguje:

JAK NASTAVIT IFS u příkazu awk?

Používám IFS=$' ' nebo IFS=$''

Mám výpis z blkid:
/dev/sda7: UUID="4FC71FC14B14ADA0" LABEL="PROGRAMY" TYPE="ntfs"
/dev/sda9: UUID="58E75A17692994A5" LABEL="ARCHIV" TYPE="ntfs"

A filtr:
fs=$(echo $line | awk '{print substr($4,7,length($4)-7)}');
Hledá typ FS na čtvrtém sloupci. A funguje správně.

Ale:
/dev/sda8: UUID="4E64923958B30394" LABEL="Fotky a hudba" TYPE="ntfs"
fs=$(echo $line | awk '{print substr($6,7,length($6)-7)}');
Nalézá na 6. sloupci. Špatně. Jak oddělovač počítá každou mezeru.

Jak to vyřešit, aby vše bylo správně pod čtvrtým sloupcem?

Dík
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 06. 04. 2010, 18:30:45
Ak na vstupe nie je oddelovac, tak sa ziadny ani cez IFS neda nastavit ... mozno by sa dal pouzit znak rovna sa ...

Vyber polozky TYPE sa da v bashi urobit napr. takto:

Kód: [Vybrat]
line='/dev/sda8: UUID="4E64923958B30394" LABEL="Fotky a hudba" TYPE="ntfs"'

fs="${line#*TYPE=\"}"
fs="${fs%\"*}"

echo "Suborovy system: $fs"
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 06. 04. 2010, 18:38:20
Ak by TYPE nebolo vzdy na konci, tak:

Kód: [Vybrat]
fs="${line#*TYPE=\"}"
fs="${fs%%\"*}"
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 06. 04. 2010, 21:49:22
Teď to ale nechápu. Myslel jsem, že když dělám v bashi jakýkoliv výpis, že ten awk to umí spolehlivě rozpoznat který odstavec je který. Jakmile v odstavci je mezera tak on to bude interpretovat špatně? Nepomohlo by nastavit IFS na tabulator? Já to zkusím.

Edit
Tak nic.

To TYPE není vždy poslední. Nepomohl by regulární výraz? Něco jako TYPE="(+)" ale nevím jak to použít a jak vytáhnout zachycený vnořený obsah
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 06. 04. 2010, 22:36:36
riesenie je vyssie (to druhe funguje pre TYPE na lubovolnej pozicii, ak samozrejme nazov tyou neobsahuje uvodzovky)... Samozrejme sa to da aj cez regularne vyrazy
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 06. 04. 2010, 23:04:40
Tak tohle už funguje. Ale potřeboval bych ještě regulární výraz na odstranění všech mezer (nebo tabulátorů), které jsou na konci řetězce.
Tohle je asi poslední bug, tak už snad nebudu mít víc otázek.
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 06. 04. 2010, 23:21:21
Citace
potřeboval bych ještě regulární výraz na odstranění všech mezer (nebo tabulátorů), které jsou na konci řetězce.

Kód: [Vybrat]
echo $line | sed -r 's/[ \t]+$//'
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 06. 04. 2010, 23:47:45
OK, dík. Ale zvláštní, nějak mi to nezabralo.

Toto je zdrojový řetězec:
'SATA XP=>$default_main_dir/XP   '

Je tam dolar, jestli to nepochopil jinak
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 07. 04. 2010, 05:35:11
A urcite je na konci medzera alebo tabulator???
Kód: [Vybrat]
echo "$line" | cat -t
Skus:
Kód: [Vybrat]
echo $line | sed -r 's/\s+$//'

Ak funguje, tak na konci bol iny znak zo skupiny whitespace
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 07. 04. 2010, 10:20:08
Tak byl tam bílý znak. Ale to se divím, vstup jsem zadával přes klávesnici jako mezeru nebo tab.

Původní pole se kterým jsem pracoval ještě obsahuje prázdné řádky (takže to špatně vypočítá počet cyklů)

attach_dirs=( "
SATA XP=>$default_main_dir/XP
PROGRAMY=>$default_main_dir/PROGRAMY
INSTALL=>$default_main_dir/INSTALL

ARCHIV=>$default_main_dir/ARCHIV
HRY=>$default_main_dir/HRY
ZALOHY=>$default_main_dir/ZALOHY
VIDEO=>$default_main_dir/VIDEO
);

když dám
Kód: [Vybrat]
echo -e $attach_dirs tak se mi nezobrazí odřádkování.

Z původního pole jsem odfiltroval prázdné řádky:
Kód: [Vybrat]
echo -e $attach_dirs | sed -r 's/^\n$//'

Ale nemám jak ověřit, že tam ty řádky nejsou, protože se mi nezobrazí v tom odřádkovaném formátu. Jak na to?
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: deadmail 07. 04. 2010, 11:46:24
Prazdne riadky sa "odfiltruju" takto (neobsahuju nic, ziaden znak):

Kód: [Vybrat]
sed '/^$/d'
Název: Re: Nahrazení řetězce pomocí reg. výrazu
Přispěvatel: webhope 07. 04. 2010, 13:36:20
Díky za pomoc. Funguje to. Teď ještě řeším problém s ukončením cyklu