多行正则表达式匹配大文件上的字符串替换

时间:2015-04-29 02:40:45

标签: regex replace sed

我有一个大的mysqldump(4+演出),我们有一个归档类型表suffers from this bug净结果是我需要将AUTO_INCREMENT计数器重置为零。是否设法进行替换,但它很难看,涉及将文件拆分成较小的块,然后点击查找表,查看我想要更改的数字,然后在原始文件上使用sed来替换只是在自动增量上匹配。就像我说的那样,可怕,但它确实有效。

所以 - 我试图破解多线sed并没有那么远。我想要做的是寻找我感兴趣的表名,然后从那一点找到下一个AUTO_INCREMENT=,然后匹配它中的数字,并使其为零。这是表:(假设在此之前和之后有大量数据)

DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `export_id` int(11) DEFAULT NULL,
  `problem_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=478 DEFAULT CHARSET=latin1;

我想要做的是(自动)扫描文件,直到匹配

(?:CREATE TABLE `archive_exported_problems).*?AUTO_INCREMENT=(\d+)

(似乎正常工作的正则表达式)然后用0

替换捕获组

我认为这是可能的 - 任何最感谢的帮助!

2 个答案:

答案 0 :(得分:2)

如果perl是一个选项,则可以更轻松地使用DOTALL中的perl标记,如下所示:

perl -00 -pe 
 's/(?s)(CREATE TABLE `archive_exported_problems`.*?AUTO_INCREMENT)=\d+/$1=0/' file.sql

DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `export_id` int(11) DEFAULT NULL,
      `problem_id` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

使用的选项是:

-00    # slurps whole file
(?s)   # enable DOTALL flag for regex

答案 1 :(得分:1)

考虑一下:

$ sed -r '/CREATE TABLE `archive_exported_problems`/,/AUTO_INCREMENT=/ {s/(AUTO_INCREMENT)=[[:digit:]]+/\1=0/;}' file
DROP TABLE IF EXISTS `archive_exported_problems`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `archive_exported_problems` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `export_id` int(11) DEFAULT NULL,
  `problem_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=ARCHIVE AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;

对于Mac OSX(BSD),请尝试:

$ sed -E -e '/CREATE TABLE `archive_exported_problems`/,/AUTO_INCREMENT=/ {s/(AUTO_INCREMENT)=[[:digit:]]+/\1=0/;}' file

如何运作

  • /CREATE TABLE archive_exported_problems /, /AUTO_INCREMENT=/

    这会将后续命令限制在以包含CREATE TABLE 'archive_exported_problems'的行开头并以包含AUTO_INCREMENT=的行结束的行上的范围。

  • s/(AUTO_INCREMENT)=[[:digit:]]+/\1=0/

    执行您想要的替换。

限制

此方法假定CREATE TABLE短语和AUTO_INCREMENT=短语永远不会出现在同一行。如果不是这样,我们需要做一些小改动。