GNU/Linux >> Znalost Linux >  >> Linux

Multi-Line Sed Vyměnit

Odpověď AWK

S vaším ukázkovým textem v souboru s názvem sql , následující vzor (se zalomením řádků a odsazením pro srozumitelnost):

awk -v skip=1 '{
    if (skip) { skip=0 }
    else {
        if (/FULLTEXT KEY/) { skip=1; sub(/,$/, "", prevline) }
        print prevline
    }
    prevline=$0
}
END { print prevline }' sql

produkuje:

CREATE TABLE `table` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `description` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

Vysvětlení:

  • Implementujeme „lookahead“ tak, že vytiskneme pouze dříve nalezený řádek při každé iteraci, po kontrole aktuálního řádku.
  • Pokud aktuální řádek obsahuje FULLTEXT KEY nastavíme příznak pro přeskočení tisku tohoto řádku během další iterace. Odstraníme také koncovou čárku na předchozím řádku, který se chystá vytisknout.
  • Přeskočíme tisk prázdného počátečního řádku (před prevline bylo nastaveno) počátečním nastavením skip1 ("pravda").
  • Ujistíme se, že vytiskneme poslední řádek tak, že skript ukončíme znakem prevline tisk. Všimněte si, že současná implementace předpokládá, že tento poslední řádek nepředstavuje řádek, u kterého hrozí riziko přeskočení, tj. že neobsahuje FULLTEXT KEY značka.

Originál (neúplný) sed odpověď

Tato odpověď je neúplná a určitě ve většině případů nesprávná, protože sed spotřebovává vstupní proud příliš rychle pro zamýšlený výsledek při provádění víceřádkového porovnávání - jak bylo uvedeno v komentářích, bude fungovat pouze pro shody na sudých řádcích! sed nemá "skutečnou" funkci dopředného vyhledávání, takže by bylo lepší použít Python/Perl/atd., nebo dokonce AWK, jak je uvedeno výše.

S vaším ukázkovým textem v souboru s názvem sql , následující vzor:

$ sed 'N; s/,\n  FULLTEXT.*//' sql

produkuje:

CREATE TABLE `table` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `description` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

Vysvětlení:

  • N umožňuje víceřádkovou shodu.
  • \n představuje zalomení řádku.
  • s/pattern/replacement/ je standardní náhradní syntaxe.
  • .* bude odpovídat čemukoli na konci aktuálního řádku.

Linux
  1. Jak nahradit text podobný sedu pythonem?

  2. Převeďte řetězec na hexadecimální na příkazovém řádku

  3. Jak nahradit řetězec ve více souborech v příkazovém řádku linuxu

  1. najít odpovídající text a nahradit další řádek

  2. nahradit n-tý výskyt řetězce v každém řádku textového souboru

  3. sed:jak nahradit řádek, pokud byl nalezen, nebo připojit na konec souboru, pokud nebyl nalezen?

  1. Jak nahradit řetězec v souboru (souborech)?

  2. Nahradit rozsah řádků rozsahem řádků (sed nebo jiné)?

  3. SED nahradit na více řádcích