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 */;
Объяснение:
- Мы реализуем "lookahead", печатая только ранее встреченную строку на каждой итерации, после проверки текущей строки.
- Если текущая строка содержит маркер
FULLTEXT KEY
, мы устанавливаем флаг, чтобы пропустить печать этой строки во время следующей итерации. Мы также удаляем запятую в предыдущей строке, которая должна быть напечатана.
- Мы пропускаем печать пустой исходной строки (до того, как был задан
prevline
), первоначально устанавливая skip
в 1
("true").
- Мы обязательно печатаем последнюю строку, заканчивая сценарий дополнительной
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/
- стандартный синтаксис замены.
.*
будет соответствовать чему-либо до конца текущей строки.