GNU/Linux >> Znalost Linux >  >> Linux

SED nahradit na více řádcích

Řešení 1:

Sed funguje na principu řádek po řádku. Může to fungovat na více řádcích, ale nebylo to tak navrženo - a podle mého názoru se to rozhodně ukáže, když se o to pokusíte. Ale pokud se rozhodnete jít touto cestou, pravděpodobně budete muset použít registry. Podívejte se na některá řešení na https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n, abyste viděli, jak to lze provést.

Pro tento druh úlohy (mám na mysli víceřádkovou orientaci) raději používám perl místo sed. Typový štítek, který musíte přidat před hledáním a nahrazením (BEGIN... ) není zřejmé, ale regulární výraz se mi zdá čistší:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Nebo pomocí seskupení zkrátit výraz a umožnit vám tam použít regulární výraz:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml

Mělo by to fungovat na výskytech s novými řádky i bez nich mezi značkami komentáře a kódem, který má být odkomentován.

Převzato z:

https://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

Řešení 2:

sed čte každý řádek postupně, takže se nikdy nebude shodovat s víceřádkovým vzorem, pokud jej nepostrčíte správným směrem. N příkaz přečte jeden řádek ze vstupu a připojí jej k prostoru vzorů.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Pravděpodobně, pokud potřebujete jiný příkaz než s , pak byste měli přepnout ze sed a na awk nebo perl. Zde je trochu flexibilnější úryvek v Perlu, který si poradí s víceřádkovými komentáři obecnějším způsobem.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml

Řešení 3:

Zde je popis víceřádkových příkazů v SED:http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

Je to bolest v zadku. Možná budete chtít následovat Eduardovy rady a použít perl -i -p -e místo toho.

Řešení 4:

  • /<\!--/ :odpovídající řetězec
  • :X :toto je označení pro příkaz větve "b"
  • /-->/ :odpovídající řetězec
  • [email protected]@[email protected] :strip "" a tisk výsledku
  • d :odstranit prostor vzoru a spustit nový cyklus
  • N :pokud se neshoduje s /-->/, přidejte řádek
  • bX :větev na :X štítek
  • p :stačí vytisknout řetězec, který se neshoduje s /