AWK の回答
サンプル テキストを sql
という名前のファイルに 、次のパターン (わかりやすくするために改行とインデントを使用):
awk -v skip=1 '{
if (skip) { skip=0 }
else {
if (/FULLTEXT KEY/) { skip=1; sub(/,$/, "", prevline) }
print prevline
}
prevline=$0
}
END { print prevline }' sql
生成:
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 */;
説明:
- 前のみを出力することで「先読み」を実装します 現在の行を検査した後、すべての反復で行に遭遇しました。
- 現在の行に
FULLTEXT KEY
が含まれている場合 次の繰り返しでこの行の印刷をスキップするフラグを設定します。また、印刷しようとしている前の行の末尾のカンマも削除します。 - 空の最初の行 (
prevline
の前) の出力をスキップします が設定されています) 最初にskip
を設定します1
まで (「真」)。 - 追加の
prevline
でスクリプトを終了することにより、最後の行を確実に出力します。 印刷します。現在の実装では、この最後の行がスキップされるリスクのある行ではないと想定していることに注意してください。つまり、FULLTEXT KEY
が含まれていない マーカー。
オリジナル (不完全) sed
答え
sed
以来、この回答は不完全であり、ほとんどの場合間違いです。 複数行のマッチングを行う場合、意図した結果に対して入力ストリームを消費する速度が速すぎます-コメントで指摘されているように、偶数行の一致に対してのみ機能します! sed
には「真の」先読み機能がないため、Python/Perl/など、または上記の AWK を使用したほうがよいでしょう。
サンプル テキストを sql
という名前のファイルに 、次のパターン:
$ sed 'N; s/,\n FULLTEXT.*//' sql
生成:
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 */;
説明:
N
複数行の一致を有効にします。\n
改行を表します。s/pattern/replacement/
標準の置換構文です。.*
現在の行の末尾に一致します。