GNU/Linux >> Belajar Linux >  >> Linux

Hapus String Multi-baris?

Ada beberapa pertanyaan di sini mengenai penggantian string multi-baris menggunakan shell Unix, tetapi saya belum menemukan satu pun yang akan berfungsi dalam situasi ini.

Saya mencoba menghapus kunci dan batasan dari beberapa DDL MySQL, yang terlihat seperti ini (satu contoh):

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;

Saya ingin menghapus semuanya dari koma yang mengakhiri baris sebelum 'PRIMARY KEY' hingga, tetapi tidak termasuk ') ENGINE=' (bisa ada nol atau beberapa baris di antara ini, dan mereka tidak akan selalu dimulai dengan KUNCI atau memiliki kurung, tetapi ') ENGINE=' konsisten). Hasilnya akan terlihat seperti ini:

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;

Saya terbuka untuk menggunakan utilitas baris perintah standar apa pun (mis. sed, perl, awk), tetapi karena file ini dapat berukuran cukup besar (beberapa berukuran puluhan atau ratusan GB), file ini harus efisien. Karena file biasanya disimpan dalam format gzip (atau terkadang saya memproses output dari utilitas dump mysql secara langsung daripada menulis ke disk terlebih dahulu), saya memerlukan sesuatu yang dapat disalurkan ke dalam dan ke luar.

Jawaban yang Diterima:

Pertahankan apakah akan mencetak baris sebelumnya, edit dikatakan untuk menghapus koma bila perlu. Metode ini hanya menyimpan satu atau dua baris file dalam memori.

#!/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. Mengotomatiskan Mengetik String Di Xmacro?

  2. Cara Menggabungkan String di Bash

  3. Perintah rm Linux

  1. Hapus pembaruan Windows yang diunduh

  2. Linux Hapus File dan Direktori

  3. Multi-Line Sed Ganti

  1. Hapus file secara rekursif dengan aman:merobek-robek

  2. Opsi Rm Untuk Gagal Pada File yang Tidak Ada?

  3. Batch menghapus informasi exif