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 menyetelskip
ke1
("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 mengandungFULLTEXT 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.
Bagaimana cara mengekstrak dan/atau menghapus halaman terakhir dari sekumpulan PDF?
Bagaimana cara mengubah judul terminal judul Terminator, ZSH di Debian?