Portál AbcLinuxu, 5. května 2025 13:07

Dotaz: Změna proměnné pomocí SED-u

13.8.2014 11:42 Jirka
Změna proměnné pomocí SED-u
Přečteno: 299×
Odpovědět | Admin
Zdravím,
od rána s tím zápasím a už jsem z toho na nervy.
Potřebuji najít tento řetězec:
{key}gain_mode0{/key}
přičemž číslo může být v rozsahu 0 až 9
a v následujícím řádku změnit:
{value}0{/value}
za
{value}False{/value}
Povedlo se mi najít pomocí sed-u ten první řádek, tímto příkazem:
sed 's/\(gain_mode[0-9]<\/key>\)/\1False/' ale nemůžu se dostat na další řádek ať dělám co dělám.
Jako pokračování jsem vyzkoušel značky \n $ ^
Ty mi nefungují.
Za pomoc děkuji. Musel jsem ručně přepsat všechny stříšky za složené závorky, tady to fórum je nepovoluje. Upozorňuji na to, aby vás to nemátlo.

Řešení dotazu:


Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Jendа avatar 13.8.2014 12:23 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
Odpovědět | | Sbalit | Link | Blokovat | Admin
tady to fórum je nepovoluje
Je to HTML. Takže &lt; a &gt;.

Zeptej se oblíbeného vyhledávač na sed match multiple lines a proklikej si prvních pár výsledků.
Jendа avatar 13.8.2014 12:24 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
Odpovědět | | Sbalit | Link | Blokovat | Admin
Tohle vypadá dobře: sed '/Lorem.*/ {N; s/Lorem.*industry\./string to replace/g}' filename
13.8.2014 13:01 Jirka
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
Tak jsem našel tenhle příkaz, který zamění pokud se nalézá mezi řádky obsahující gain_mode a param (bohužel včetně). A protože mi pak zamění i ten první řádek, tak jej musím druhým příkazem opravit. Udělal jsem to tedy takto:

sed '/gain_mode[0-9]<\/key>/,/param/s/0/False/g;s/modeFalse/mode0/'

Teď by mě ještě zajímalo, jak to udělat, aby to udělalo ve všech souborech v daném adresáři? Stačí přidat hvězdičku na konec?
13.8.2014 13:51 Alena
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
sed -i "s/bla/ble/" *.txt
Řešení 1× (Tarmaq)
13.8.2014 14:08 Jirka
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
Super dík. Takže tohle chodí:

sed -i '/gain_mode[0-9]/,/param/s/0/False/g;s/modeFalse/mode0/' *.grc
13.8.2014 14:36 Jirka
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
A takhle mi to udělá ve všech podadresářích:

find . -type f -name '*.grc' -exec sed -i '/gain_mode[0-9]/,/param/s/0/False/g;s/modeFalse/mode0/' {} \;

Mimochodem jedná se o aktualizaci GNURadio z verze 3.7.2 na verzi 3.7.3, kdy mi všechny staré skripty přestaly naráz fungovat a tahle "oprava" to vyřešila. Ručně to nešlo.
Jendа avatar 13.8.2014 17:56 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
A teď upgraduješ na 3.7.4 :-).

Ta nestabilita napříč verzemi je fakt strašná.
17.8.2014 09:35 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Změna proměnné pomocí SED-u
Odpovědět | | Sbalit | Link | Blokovat | Admin
tady to fórum je nepovoluje

>>> Opravdu? <<<

Proč zrovna sed? Podle mě je na to lepší awk. Výstřel od boku (zcela jistě s chybami):

#!/usr/bin/awk -f

BEGIN { state = 0 }
state {
        print "<value>False</value>"
        state = 0
        next
}
/<key>gain_mode[0-9]<\/key>/ { state = 1 }
{ print $0 }

První možnost je nazvat ten skript třeba convertor a pak spustit ./convertor < vstup > výstup. Druhá možnost je dát celý zdroják awk jako parametr, tj.

awk 'BEGIN { state = 0 } state { print "<value>False</value>"; state = 0; next } /<key>gain_mode[0-9]<\/key>/ { state = 1 } { print $0 }' < vstup > výstup

Kdyby náhodou mohl existovat <key> bez <value> nebo pokud je potřeba měnit hodnotu jen tehdy, byla-li původně 0, stačí pozměnit podmínku u druhé klauzule, tj. místo state { … } tam dát například state && /<value>0<\/value>/ { … } To už záleží na tom, jaké je přesně zadání problému.

Vše výše zmíněné platí v případě, že <key> a <value> jsou vždy samostatně na jednom řádku. Jinak by bylo potřeba doplnit do regulárních výrazů podle potřeby ^ a $, případně místo nahrazení celé řádky použít funkce sub() nebo gsub() v awk — podle toho, jakým způsobem je třeba celý filtr omezit nebo rozšířit. Příkladem použití sub() by bylo odstranění next z druhé klauzule a nahrazení print "<value>False</value>" nad tím za sub(/<value>0<\/value>/, "<value>False</value>"). (sub() v tomto tvaru provede náhradu přímo v proměnné $0, která obsahuje celý řádek, a poslední klauzule pak (díky odstranění next) řádek vypíše.)

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.