GNU/Linux >> Znalost Linux >  >> Linux

Smazat víceřádkové řetězce?

Bylo zde několik otázek týkajících se nahrazení víceřádkových řetězců pomocí unixového shellu, ale nenašel jsem žádný, který by v této situaci fungoval.

Snažím se odstranit klíče a omezení z některých MySQL DDL, které vypadají takto (jeden příklad):

CREATE TABLE `access_group` (
  `GROUP_ID` int(10) NOT NULL AUTO_INCREMENT,
  `PARENT_GROUP_ID` int(10) DEFAULT NULL,
  `GROUP_NAME` varchar(45) NOT NULL,
  `GROUP_DESC` varchar(45) NOT NULL DEFAULT '',
  PRIMARY KEY (`GROUP_ID`),
  KEY `testkey` (`PARENT_GROUP_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1;

Chci odstranit vše od čárky končící řádek před 'PRIMARY KEY' až po, ale ne včetně ') ENGINE=' (mezi nimi může být nula nebo více řádků a nebudou vždy začínat KEY nebo mít závorky, ale ') ENGINE=' je konzistentní). Výsledek by měl vypadat takto:

CREATE TABLE `access_group` (
  `GROUP_ID` int(10) NOT NULL AUTO_INCREMENT,
  `PARENT_GROUP_ID` int(10) DEFAULT NULL,
  `GROUP_NAME` varchar(45) NOT NULL,
  `GROUP_DESC` varchar(45) NOT NULL DEFAULT ''
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=latin1;

Jsem otevřený použití jakéhokoli standardního nástroje příkazového řádku (např. sed, perl, awk), ale protože tyto soubory mohou být poměrně velké (některé jsou v řádu desítek nebo stovek GB), musí být efektivní. Vzhledem k tomu, že soubory jsou obvykle uloženy ve formátu gzip (nebo někdy zpracuji výstup nástroje mysql dump přímo, místo toho, abych nejprve zapisoval na disk), potřebuji něco, co lze pomocí pipetování a zpět.

Přijatá odpověď:

Ponechte stav, zda chcete vytisknout předchozí řádek, v případě potřeby čárku odstraňte. Tato metoda uchovává v paměti pouze jeden nebo dva řádky souboru.

#!/usr/bin/env perl
use strict;
use warnings;

my $printing = 1;
my $previous;

# reads from standard input (optionally with the conventional -) or from
# the named files
shift @ARGV if @ARGV == 1 and $ARGV[0] eq '-';
while ( my $line = readline ) {
    if ( $line =~ m/^\s+PRIMARY KEY/ ) {
        $previous =~ s/,[ \t]*$//;
        $printing = 0;
    } elsif ( $line =~ m/^\) ENGINE/ ) {
        $printing = 1;
    } elsif ( !$printing ) {
        undef $previous;
    }
    print $previous if defined $previous;
    $previous = $line if $printing;
}
# don't forget last line after fall off the end of input (eof)
print $previous if defined $previous;

Linux
  1. Rekurzivně mazat soubory bezpečně:skartace

  2. Možnost Rm selhat u neexistujících souborů?

  3. Automatizace textových řetězců v Xmacro?

  1. Přemapování vypínače k ​​odstranění?

  2. Jak odstranit službu v Kubernetes

  3. Jak zřetězit řetězce v Bash

  1. Linuxový příkaz rm

  2. Odstraňte stažené aktualizace systému Windows

  3. Linux Odstraňte soubory a adresáře