次のテキスト(ちなみに、MySQLダンプの一部)について考えてみます。
CREATE TABLE `table`( ` id` int(10)NOT NULL auto_increment、 `name` varchar(100)NOT NULL default ''、 `description` text NOT NULL、 PRIMARY KEY(` id`)、 FULLTEXT KEY `full_index`(` name`) )ENGINE = MyISAM DEFAULT CHARSET = latin1; /*!40101 SET character_set_client = @saved_cs_client * /;
FULLTEXT
キーを削除したいのですが、SQLが有効なままになるように、上の行の末尾のコンマも削除したいと思います。
誰かがこれを行うためのsed
レシピを思い付く(そして説明する)ことができますか?
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
を1
( "true")に設定することにより、(skip
が設定される前の)空の最初の行の印刷をスキップします。prevline
printで終了して、最後の行を印刷してください。現在の実装では、この最後の行がスキップされるリスクのない行であると想定していることに注意してください。つまり、FULLTEXT KEY
マーカーが含まれていません。sed
回答この回答は不完全であり、ほとんどの場合正しくありません。sed
は、複数行のマッチングを行うと、意図した結果に対して入力ストリームをすぐに消費するためです-コメントで指摘されているように、機能するだけです偶数行の一致の場合!sed
には「真の」先読み機能がないため、Python/Perl/etcなど、または実際には上記の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/
は標準の置換構文です。.*
は、現在の行の末尾に一致します。Sedで2行を管理することはそれほど難しくありません。
パターンスペースに2行入れてください。
sed -n '$!N; s/,[[:space:]]*FULLTEXT KEY.*// ;P;D'