GNU/Linux >> Belajar Linux >  >> Linux

Multi-Line Sed Ganti

Jawaban AWK

Dengan contoh teks Anda dalam file bernama sql , pola berikut (dengan jeda baris dan lekukan untuk kejelasan):

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

menghasilkan:

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

Penjelasan:

  • Kami menerapkan "lookahead" dengan hanya mencetak sebelumnya baris yang ditemui di setiap iterasi, setelah memeriksa baris saat ini.
  • Jika baris saat ini berisi FULLTEXT KEY penanda, kami menyetel bendera untuk melewati pencetakan baris ini selama iterasi berikutnya. Kami juga menghapus tanda koma pada baris sebelumnya yang akan dicetak.
  • Kami melewati pencetakan baris awal kosong (sebelum prevline telah disetel) dengan awalnya menyetel skip ke 1 ("benar").
  • Kami memastikan untuk mencetak baris terakhir dengan mengakhiri skrip dengan tambahan prevline mencetak. Perhatikan bahwa implementasi saat ini mengasumsikan bahwa baris terakhir ini bukan baris yang berisiko dilewati, yaitu tidak mengandung FULLTEXT KEY penanda.

Asli (tidak lengkap) sed jawab

Jawaban ini tidak lengkap dan pasti dalam banyak kasus salah, sejak sed akan menggunakan aliran input terlalu cepat untuk hasil yang diinginkan saat melakukan pencocokan multiline -- seperti yang ditunjukkan dalam komentar, ini hanya akan berfungsi untuk pencocokan pada baris bernomor genap! sed tidak memiliki fungsionalitas lookahead yang "benar", jadi kami akan lebih baik menggunakan Python/Perl/dll., atau memang AWK seperti di atas.

Dengan contoh teks Anda dalam file bernama sql , pola berikut:

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

menghasilkan:

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

Penjelasan:

  • N mengaktifkan pencocokan multiline.
  • \n mewakili jeda baris.
  • s/pattern/replacement/ adalah sintaks pengganti standar.
  • .* akan mencocokkan apa pun dengan akhir baris saat ini.

Linux
  1. Menggunakan Sed untuk Mencari &mengganti garis di antara rentang pola

  2. Bagaimana Cara Menggunakan Sed Atau Ex Untuk Mengganti Blok (Kode multi-baris) Dengan Blok Teks (kode) Baru?

  3. Bisakah Sed Mengganti Karakter Baris Baru?

  1. Sed Pada Osx Masukkan Pada Garis Tertentu?

  2. ganti kemunculan string ke-n di setiap baris file teks

  3. SED ganti di beberapa baris

  1. Bagaimana Cara Mengganti String Dalam File?

  2. Bagaimana Cara Menggunakan Sed Untuk Mengganti String Multi-baris?

  3. Ganti Rentang Garis Dengan Rentang Garis (sed Atau Lainnya)?