GNU/Linux >> Znalost Linux >  >> Linux

Vytiskněte čáry mezi počátečním a koncovým vzorem, ale pokud koncový vzor neexistuje, netiskněte

Můžete to provést následovně:

$ sed -e '
    /BEGIN/,/END/!d
    H;/BEGIN/h;/END/!d;g
' inp

Funguje to tak, že pro počáteční/koncový rozsah řádků je ukládá do úložného prostoru. Poté maže, dokud nenarazíte na řádek END. V tomto okamžiku si připomeneme, co je v držení. OTW, nic nedostaneme. HTH.


cat input |
sed '/\*\*\*\*\* BEGIN \*\*\*\*\*/,/\*\*\*\*\* END *\*\*\*\*/ p;d' | 
tac |
sed '/\*\*\*\*\* END \*\*\*\*\*/,/\*\*\*\*\* BEGIN *\*\*\*\*/ p;d' |
tac

Funguje to tak, že máte tac otočit řádky tak, aby sed můžete najít oba oddělovače v obou řádech.


S pcregrep :

pcregrep -M '(?s)BEGIN.*?END'

To také funguje, pokud jsou BEGIN a END na stejném řádku, ale ne v případech jako:

BEGIN 1 END foo BEGIN 2
END

Kde pcregrep zachytí první BEGIN 1 END , ale ne ten druhý.

Chcete-li to zvládnout, pomocí awk , můžete udělat:

awk '
  !inside {
    if (match($0, /^.*BEGIN/)) {
      inside = 1
      remembered = substr($0, 1, RLENGTH)
      $0 = substr($0, RLENGTH + 1)
    } else next
  }
  {
    if (match($0, /^.*END/)) {
      print remembered $0
      if (substr($0, RLENGTH+1) ~ /BEGIN/)
        remembered = ""
      else
        inside = 0
    } else
      remembered = remembered $0 ORS
  }'

Na vstupu jako:

a
BEGIN blah END BEGIN 1
2
END
b
BEGIN foo END
c
BEGIN
bar
END BEGIN
baz END
d
BEGIN
xxx

To dává:

BEGIN blah END BEGIN 1
2
END
BEGIN foo END
BEGIN
bar
END BEGIN
baz END

Oba potřebují do paměti uložit vše od ZAČÁTKU po následující KONEC. Takže pokud máte velký soubor, jehož první řádek obsahuje BEGIN, ale bez KONCE, celý soubor bude uložen v paměti pro nic.

Jediný způsob, jak to obejít, by bylo zpracovat soubor dvakrát, ale to lze samozřejmě provést pouze tehdy, když je vstupem běžný soubor (ne například roura).


Linux
  1. Linux:zkopírujte a vytvořte cílový adresář, pokud neexistuje

  2. open() v Pythonu nevytvoří soubor, pokud neexistuje

  3. Připojení řádku k souboru pouze v případě, že ještě neexistuje

  1. Linux zdarma ukazuje vysoké využití paměti, ale top ne

  2. Mount Point neexistuje, přestože jej vytvořil

  3. Grep řádky začínající 1, ale ne 10, 11, 100 atd

  1. Jak Grep linky, které nezačínají "#" nebo ";"?

  2. Proč Tomcat pracuje s portem 8080, ale ne s 80?

  3. PHP-FPM se po restartu automaticky nespustí