GNU/Linux >> Linux Esercitazione >  >> Linux

Sostituzione Sed multilinea

Risposta AWK

Con il tuo testo di esempio in un file chiamato sql , il seguente modello (con interruzioni di riga e indentazione per chiarezza):

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

produce:

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 */;

Spiegazione:

  • Implementiamo "lookahead" stampando solo precedentemente riga incontrata ad ogni iterazione, dopo aver ispezionato la riga corrente.
  • Se la riga corrente contiene il FULLTEXT KEY marker, impostiamo un flag per saltare la stampa di questa riga durante l'iterazione successiva. Rimuoviamo anche la virgola finale sulla riga precedente che sta per essere stampata.
  • Saltiamo la stampa di una riga iniziale vuota (prima di prevline è stato impostato) impostando inizialmente skip a 1 ("vero").
  • Ci assicuriamo di stampare l'ultima riga terminando lo script con un ulteriore prevline Stampa. Si noti che l'attuale implementazione presuppone che quest'ultima riga non sia una riga a rischio di essere saltata, cioè che non contenga il FULLTEXT KEY marcatore.

Originale (incompleto) sed rispondi

Questa risposta è incompleta e certamente nella maggior parte dei casi errata, poiché sed consumerà il flusso di input troppo rapidamente per il risultato desiderato quando si esegue la corrispondenza multilinea - come sottolineato nei commenti, funzionerà solo per le corrispondenze su righe pari! sed non ha una "vera" funzionalità di previsione, quindi sarebbe meglio usare Python/Perl/ecc., o addirittura AWK come sopra.

Con il tuo testo di esempio in un file chiamato sql , il seguente modello:

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

produce:

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 */;

Spiegazione:

  • N abilita la corrispondenza multilinea.
  • \n rappresenta un'interruzione di riga.
  • s/pattern/replacement/ è la sintassi di sostituzione standard.
  • .* corrisponderà a qualsiasi cosa fino alla fine della riga corrente.

Linux
  1. Come utilizzare Sed per sostituire una stringa multilinea?

  2. Come utilizzare Sed o Ex per sostituire un blocco (codice multilinea) con un nuovo blocco di testo (codice)?

  3. Sostituire Intervallo di linee con Intervallo di linee (sed o altro)?

  4. trova il testo corrispondente e sostituisci la riga successiva

  5. sostituire le righe in un file con le righe in un altro per numero di riga

I 20 migliori comandi sed da usare

Tutorial Unix Sed:aggiungi, inserisci, sostituisci e conta righe di file

Tutorial Unix Sed:operazione su file multilinea con 6 esempi pratici

sostituire l'ennesima occorrenza di stringa in ogni riga di un file di testo

sed:come sostituire la riga se trovata o aggiungere alla fine del file se non trovata?

Sostituzione SED su più righe